use {Future, Poll, Async}; /// Future for the `select` combinator, waiting for one of two futures to /// complete. /// /// This is created by the `Future::select` method. #[derive(Debug)] #[must_use = "futures do nothing unless polled"] pub struct Select where A: Future, B: Future { inner: Option<(A, B)>, } /// Future yielded as the second result in a `Select` future. /// /// This sentinel future represents the completion of the second future to a /// `select` which finished second. #[derive(Debug)] #[must_use = "futures do nothing unless polled"] pub struct SelectNext where A: Future, B: Future { inner: OneOf, } #[derive(Debug)] enum OneOf where A: Future, B: Future { A(A), B(B), } pub fn new(a: A, b: B) -> Select where A: Future, B: Future { Select { inner: Some((a, b)), } } impl Future for Select where A: Future, B: Future, { type Item = (A::Item, SelectNext); type Error = (A::Error, SelectNext); fn poll(&mut self) -> Poll { let (ret, is_a) = match self.inner { Some((ref mut a, ref mut b)) => { match a.poll() { Err(a) => (Err(a), true), Ok(Async::Ready(a)) => (Ok(a), true), Ok(Async::NotReady) => { match b.poll() { Err(a) => (Err(a), false), Ok(Async::Ready(a)) => (Ok(a), false), Ok(Async::NotReady) => return Ok(Async::NotReady), } } } } None => panic!("cannot poll select twice"), }; let (a, b) = self.inner.take().unwrap(); let next = if is_a {OneOf::B(b)} else {OneOf::A(a)}; let next = SelectNext { inner: next }; match ret { Ok(a) => Ok(Async::Ready((a, next))), Err(e) => Err((e, next)), } } } impl Future for SelectNext where A: Future, B: Future, { type Item = A::Item; type Error = A::Error; fn poll(&mut self) -> Poll { match self.inner { OneOf::A(ref mut a) => a.poll(), OneOf::B(ref mut b) => b.poll(), } } }