use core::future::Future; use core::pin::Pin; use core::task::{Context, Poll}; #[derive(Debug, Clone)] pub enum Either { Left(A), Right(B), } pub fn select(a: A, b: B) -> Select where A: Future, B: Future, { Select { a, b } } pub struct Select { a: A, b: B, } impl Unpin for Select {} impl Future for Select where A: Future, B: Future, { type Output = Either; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = unsafe { self.get_unchecked_mut() }; let a = unsafe { Pin::new_unchecked(&mut this.a) }; let b = unsafe { Pin::new_unchecked(&mut this.b) }; match a.poll(cx) { Poll::Ready(x) => Poll::Ready(Either::Left(x)), Poll::Pending => match b.poll(cx) { Poll::Ready(x) => Poll::Ready(Either::Right(x)), Poll::Pending => Poll::Pending, }, } } }