future_utils/
while_driving.rs1use futures::{Async, Future};
2use std::mem;
3
4pub struct WhileDriving<A, B: Future> {
5 inner: WhileDrivingInner<A, B>,
6}
7
8enum WhileDrivingInner<A, B: Future> {
9 Driving(A, B),
10 Drove(A, Result<B::Item, B::Error>),
11 Finished,
12}
13
14impl<A, B: Future> WhileDriving<A, B> {
15 pub fn new(a: A, b: B) -> WhileDriving<A, B> {
16 WhileDriving {
17 inner: WhileDrivingInner::Driving(a, b),
18 }
19 }
20}
21
22impl<A, B> Future for WhileDriving<A, B>
23where
24 A: Future,
25 B: Future,
26{
27 type Item = (A::Item, Finish<B>);
28 type Error = (A::Error, Finish<B>);
29
30 fn poll(&mut self) -> Result<Async<(A::Item, Finish<B>)>, (A::Error, Finish<B>)> {
31 let inner = mem::replace(&mut self.inner, WhileDrivingInner::Finished);
32 match inner {
33 WhileDrivingInner::Driving(mut a, mut b) => {
34 match a.poll() {
35 Ok(Async::Ready(x)) => {
36 let finish = Finish {
37 state: FinishState::Inner(FinishInner::Running(b)),
38 };
39 Ok(Async::Ready((x, finish)))
40 },
41 Ok(Async::NotReady) => {
42 match b.poll() {
43 Ok(Async::Ready(x)) => {
44 self.inner = WhileDrivingInner::Drove(a, Ok(x));
45 },
46 Ok(Async::NotReady) => {
47 self.inner = WhileDrivingInner::Driving(a, b);
48 },
49 Err(e) => {
50 self.inner = WhileDrivingInner::Drove(a, Err(e));
51 },
52 }
53 Ok(Async::NotReady)
54 },
55 Err(e) => {
56 let finish = Finish {
57 state: FinishState::Inner(FinishInner::Running(b)),
58 };
59 Err((e, finish))
60 },
61 }
62 },
63 WhileDrivingInner::Drove(mut a, res) => {
64 match a.poll() {
65 Ok(Async::Ready(x)) => {
66 let finish = Finish {
67 state: FinishState::Inner(FinishInner::Ran(res)),
68 };
69 Ok(Async::Ready((x, finish)))
70 },
71 Ok(Async::NotReady) => {
72 self.inner = WhileDrivingInner::Drove(a, res);
73 Ok(Async::NotReady)
74 },
75 Err(e) => {
76 let finish = Finish {
77 state: FinishState::Inner(FinishInner::Ran(res)),
78 };
79 Err((e, finish))
80 },
81 }
82 },
83 WhileDrivingInner::Finished => {
84 panic!("poll() called on WhileDriving which has already finished");
85 },
86 }
87 }
88}
89
90pub struct Finish<B: Future> {
93 state: FinishState<B>,
94}
95
96impl<B: Future> Finish<B> {
97 pub fn into_inner(self) -> FinishInner<B> {
98 match self.state {
99 FinishState::Inner(inner) => inner,
100 FinishState::Finished => {
101 panic!("into_inner() called on Finish which has already finished");
102 },
103 }
104 }
105}
106
107pub enum FinishInner<B: Future> {
108 Running(B),
109 Ran(Result<B::Item, B::Error>),
110}
111
112enum FinishState<B: Future> {
113 Inner(FinishInner<B>),
114 Finished,
115}
116
117impl<B: Future> Future for Finish<B> {
118 type Item = B::Item;
119 type Error = B::Error;
120
121 fn poll(&mut self) -> Result<Async<B::Item>, B::Error> {
122 let state = mem::replace(&mut self.state, FinishState::Finished);
123 match state {
124 FinishState::Inner(FinishInner::Running(mut b)) => {
125 match b.poll() {
126 Ok(Async::Ready(x)) => {
127 Ok(Async::Ready(x))
128 },
129 Ok(Async::NotReady) => {
130 self.state = FinishState::Inner(FinishInner::Running(b));
131 Ok(Async::NotReady)
132 },
133 Err(e) => {
134 Err(e)
135 },
136 }
137 },
138 FinishState::Inner(FinishInner::Ran(res)) => Ok(Async::Ready(res?)),
139 FinishState::Finished => {
140 panic!("poll() called on Finish which has already finished");
141 },
142 }
143 }
144}
145