tokio_resource_pool/
machine.rs1use 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}