1use futures::{Future, IntoFuture, Poll};
3
4pub trait FutureExt: Future + Sized {
6 fn select_either<B>(self, other: B) -> futures::SelectEither<Self, B::Future>
32 where
33 B: IntoFuture,
34 {
35 impls::select_either(self, other.into_future())
36 }
37}
38impl<T: Future> FutureExt for T {}
39
40pub mod futures {
41 pub use super::impls::SelectEither;
43}
44
45mod impls {
46 use futures::{Future, Poll, Async};
47 use futures::future::Either;
48
49 pub fn select_either<A: Future, B: Future>(a: A, b: B) -> SelectEither<A, B> {
50 SelectEither(Some((a, b)))
51 }
52
53 pub struct SelectEither<A, B>(Option<(A, B)>);
57 impl<A, B> Future for SelectEither<A, B>
58 where
59 A: Future,
60 B: Future,
61 {
62 type Item = Either<(A::Item, B), (A, B::Item)>;
63 type Error = Either<(A::Error, B), (A, B::Error)>;
64 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
65 let (mut a, mut b) = self.0.take().expect("Cannot poll SelectEither twice");
66 match a.poll() {
67 Err(e) => return Err(Either::A((e, b))),
68 Ok(Async::Ready(v)) => return Ok(Async::Ready(Either::A((v, b)))),
69 Ok(Async::NotReady) => {}
70 }
71 match b.poll() {
72 Err(e) => return Err(Either::B((a, e))),
73 Ok(Async::Ready(v)) => return Ok(Async::Ready(Either::B((a, v)))),
74 Ok(Async::NotReady) => {}
75 }
76 self.0 = Some((a, b));
77 Ok(Async::NotReady)
78 }
79 }
80}
81
82#[derive(Debug)]
84#[allow(missing_docs)]
85pub enum Phase<A, B = A, C = B, D = C, E = D> {
86 A(A),
87 B(B),
88 C(C),
89 D(D),
90 E(E),
91}
92#[cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
93impl<A, B, C, D, E> Future for Phase<A, B, C, D, E>
94where
95 A: Future,
96 B: Future,
97 C: Future,
98 D: Future,
99 E: Future,
100{
101 type Item = Phase<A::Item, B::Item, C::Item, D::Item, E::Item>;
102 type Error = Phase<A::Error, B::Error, C::Error, D::Error, E::Error>;
103 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
104 match *self {
105 Phase::A(ref mut f) => f.poll().map(|v| v.map(Phase::A)).map_err(Phase::A),
106 Phase::B(ref mut f) => f.poll().map(|v| v.map(Phase::B)).map_err(Phase::B),
107 Phase::C(ref mut f) => f.poll().map(|v| v.map(Phase::C)).map_err(Phase::C),
108 Phase::D(ref mut f) => f.poll().map(|v| v.map(Phase::D)).map_err(Phase::D),
109 Phase::E(ref mut f) => f.poll().map(|v| v.map(Phase::E)).map_err(Phase::E),
110 }
111 }
112}