future_utils/
first_ok2.rs

1use futures::{Future, Async};
2use std::mem;
3
4pub struct FirstOk2<A: Future, B: Future> {
5    inner: FirstOk2Inner<A, B>,
6}
7
8impl<A: Future, B: Future> FirstOk2<A, B> {
9    pub fn new(a: A, b: B) -> FirstOk2<A, B> {
10        FirstOk2 {
11            inner: FirstOk2Inner::BothRunning(a, b),
12        }
13    }
14}
15
16enum FirstOk2Inner<A: Future, B: Future> {
17    BothRunning(A, B),
18    RunningA(A, B::Error),
19    RunningB(A::Error, B),
20    Finished,
21}
22
23impl<A, B> Future for FirstOk2<A, B>
24where
25    A: Future,
26    B: Future<Item=A::Item>
27{
28    type Item = A::Item;
29    type Error = (A::Error, B::Error);
30
31    fn poll(&mut self) -> Result<Async<A::Item>, (A::Error, B::Error)> {
32        let inner = mem::replace(&mut self.inner, FirstOk2Inner::Finished);
33        match inner {
34            FirstOk2Inner::BothRunning(mut a, mut b) => {
35                match a.poll() {
36                    Ok(Async::Ready(x)) => Ok(Async::Ready(x)),
37                    Ok(Async::NotReady) => {
38                        match b.poll() {
39                            Ok(Async::Ready(x)) => Ok(Async::Ready(x)),
40                            Ok(Async::NotReady) => {
41                                self.inner = FirstOk2Inner::BothRunning(a, b);
42                                Ok(Async::NotReady)
43                            },
44                            Err(eb) => {
45                                self.inner = FirstOk2Inner::RunningA(a, eb);
46                                Ok(Async::NotReady)
47                            },
48                        }
49                    },
50                    Err(ea) => {
51                        match b.poll() {
52                            Ok(Async::Ready(x)) => Ok(Async::Ready(x)),
53                            Ok(Async::NotReady) => {
54                                self.inner = FirstOk2Inner::RunningB(ea, b);
55                                Ok(Async::NotReady)
56                            },
57                            Err(eb) => Err((ea, eb)),
58                        }
59                    },
60                }
61            },
62            FirstOk2Inner::RunningA(mut a, eb) => {
63                match a.poll() {
64                    Ok(Async::Ready(x)) => Ok(Async::Ready(x)),
65                    Ok(Async::NotReady) => {
66                        self.inner = FirstOk2Inner::RunningA(a, eb);
67                        Ok(Async::NotReady)
68                    },
69                    Err(ea) => Err((ea, eb)),
70                }
71            },
72            FirstOk2Inner::RunningB(ea, mut b) => {
73                match b.poll() {
74                    Ok(Async::Ready(x)) => Ok(Async::Ready(x)),
75                    Ok(Async::NotReady) => {
76                        self.inner = FirstOk2Inner::RunningB(ea, b);
77                        Ok(Async::NotReady)
78                    },
79                    Err(eb) => Err((ea, eb)),
80                }
81            },
82            FirstOk2Inner::Finished => {
83                panic!("poll() called on FirstOk2 which has already finished");
84            },
85        }
86    }
87}
88