use std::async_iter::AsyncIterator;
use std::future::Future;
use std::pin::Pin;
use std::task::{self, Poll};
pub const fn either<Fut1, Fut2>(future1: Fut1, future2: Fut2) -> Either<Fut1, Fut2> {
Either { future1, future2 }
}
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Either<Fut1, Fut2> {
future1: Fut1,
future2: Fut2,
}
impl<Fut1, Fut2> Future for Either<Fut1, Fut2>
where
Fut1: Future,
Fut2: Future,
{
type Output = Result<Fut1::Output, Fut2::Output>;
fn poll(mut self: Pin<&mut Self>, ctx: &mut task::Context<'_>) -> Poll<Self::Output> {
let future1 = unsafe { Pin::map_unchecked_mut(self.as_mut(), |s| &mut s.future1) };
match future1.poll(ctx) {
Poll::Ready(value) => Poll::Ready(Ok(value)),
Poll::Pending => {
let future2 = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.future2) };
match future2.poll(ctx) {
Poll::Ready(value) => Poll::Ready(Err(value)),
Poll::Pending => Poll::Pending,
}
}
}
}
}
pub const fn next<I>(iter: I) -> Next<I> {
Next { iter }
}
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Next<I> {
iter: I,
}
impl<I> Future for Next<I>
where
I: AsyncIterator,
{
type Output = Option<I::Item>;
fn poll(self: Pin<&mut Self>, ctx: &mut task::Context<'_>) -> Poll<Self::Output> {
unsafe { Pin::map_unchecked_mut(self, |s| &mut s.iter).poll_next(ctx) }
}
}