1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
use std::pin::Pin; use crate::future::MaybeDone; use pin_project_lite::pin_project; use crate::task::{Context, Poll}; use std::future::Future; pin_project! { #[allow(missing_docs)] #[allow(missing_debug_implementations)] pub struct TryJoin<L, R> where L: Future, R: Future, { #[pin] left: MaybeDone<L>, #[pin] right: MaybeDone<R>, } } impl<L, R> TryJoin<L, R> where L: Future, R: Future, { pub(crate) fn new(left: L, right: R) -> Self { Self { left: MaybeDone::new(left), right: MaybeDone::new(right), } } } impl<L, R, A, B, E> Future for TryJoin<L, R> where L: Future<Output = Result<A, E>>, R: Future<Output = Result<B, E>>, { type Output = Result<(A, B), E>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { let this = self.project(); let mut left = this.left; let mut right = this.right; if Future::poll(Pin::new(&mut left), cx).is_ready() { if left.as_ref().output().unwrap().is_err() { return Poll::Ready(Err(left.take().unwrap().err().unwrap())); } else if right.as_ref().output().is_some() { return Poll::Ready(Ok(( left.take().unwrap().ok().unwrap(), right.take().unwrap().ok().unwrap(), ))); } } if Future::poll(Pin::new(&mut right), cx).is_ready() { if right.as_ref().output().unwrap().is_err() { return Poll::Ready(Err(right.take().unwrap().err().unwrap())); } else if left.as_ref().output().is_some() { return Poll::Ready(Ok(( left.take().unwrap().ok().unwrap(), right.take().unwrap().ok().unwrap(), ))); } } Poll::Pending } }