Skip to main content

volans_core/
either.rs

1use either::Either;
2use futures::{TryFuture, future};
3use pin_project::pin_project;
4
5use std::{
6    pin::Pin,
7    task::{Context, Poll},
8};
9
10#[pin_project(project = EitherFutureProj)]
11#[derive(Debug, Copy, Clone)]
12#[must_use = "futures do nothing unless polled"]
13pub enum EitherFuture<A, B> {
14    First(#[pin] A),
15    Second(#[pin] B),
16}
17
18impl<A, B, AOk, BOk> Future for EitherFuture<A, B>
19where
20    A: TryFuture<Ok = AOk>,
21    B: TryFuture<Ok = BOk>,
22{
23    type Output = Result<future::Either<AOk, BOk>, Either<A::Error, B::Error>>;
24
25    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
26        match self.project() {
27            EitherFutureProj::First(a) => match a.try_poll(cx) {
28                Poll::Ready(Ok(ok)) => Poll::Ready(Ok(future::Either::Left(ok))),
29                Poll::Ready(Err(err)) => Poll::Ready(Err(Either::Left(err))),
30                Poll::Pending => Poll::Pending,
31            },
32            EitherFutureProj::Second(b) => match b.try_poll(cx) {
33                Poll::Ready(Ok(ok)) => Poll::Ready(Ok(future::Either::Right(ok))),
34                Poll::Ready(Err(err)) => Poll::Ready(Err(Either::Right(err))),
35                Poll::Pending => Poll::Pending,
36            },
37        }
38    }
39}