use pin_project_lite::pin_project; use std::{ future::Future, pin::Pin, task::{Context, Poll}, }; pin_project! { /// One of two possible futures that have the same output type. #[project = EitherProj] pub(crate) enum Either { Left { #[pin] fut: F1 }, Right { #[pin] fut: F2, }, } } impl Either { pub(crate) fn left(fut: F1) -> Self { Either::Left { fut } } pub(crate) fn right(fut: F2) -> Self { Either::Right { fut } } } impl Future for Either where F1: Future, F2: Future, { type Output = F1::Output; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { match self.project() { EitherProj::Left { fut } => fut.poll(cx), EitherProj::Right { fut } => fut.poll(cx), } } }