tokio_resource_pool/
machine.rs

1use std::mem;
2
3use futures::{Async, Future, Poll};
4
5pub enum Turn<S>
6where
7    S: State,
8{
9    Continue(S),
10    Suspend(S),
11    Done(S::Final),
12}
13
14pub trait State: Sized {
15    type Final;
16
17    type Item;
18
19    type Error;
20
21    type Context;
22
23    fn turn(state: Self, context: &mut Self::Context) -> Result<Turn<Self>, Self::Error>;
24
25    fn finalize(f: Self::Final, context: Self::Context) -> Result<Self::Item, Self::Error>;
26}
27
28pub struct Machine<S>
29where
30    S: State,
31{
32    state: Option<S>,
33    context: Option<S::Context>,
34}
35
36impl<S> Machine<S>
37where
38    S: State,
39{
40    pub fn new(state: S, context: S::Context) -> Self {
41        Self {
42            state: Some(state),
43            context: Some(context),
44        }
45    }
46}
47
48impl<S> Future for Machine<S>
49where
50    S: State,
51{
52    type Item = S::Item;
53
54    type Error = S::Error;
55
56    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
57        let mut state = mem::replace(&mut self.state, None).unwrap();
58        loop {
59            let turn = S::turn(state, self.context.as_mut().unwrap())?;
60
61            match turn {
62                Turn::Continue(next_state) => {
63                    state = next_state;
64                }
65                Turn::Suspend(next_state) => {
66                    self.state = Some(next_state);
67                    return Ok(Async::NotReady);
68                }
69                Turn::Done(fin) => {
70                    let context = self.context.take().unwrap();
71                    return S::finalize(fin, context).map(Async::Ready);
72                }
73            }
74        }
75    }
76}