use std::{
convert::Infallible,
ops::ControlFlow,
pin::Pin,
task::{Context, Poll},
};
use futures::{Stream, TryStream};
use crate::{
selector::{BorrowedMut, Id, Removed},
task::Task,
};
#[derive(Debug, Clone, Copy, Default)]
pub struct FutureBasic;
impl<F: Future> Task<FutureBasic> for F {
type Cont = Infallible;
type Break = F::Output;
type Output = F::Output;
fn poll_progress(
self: Pin<&mut Self>,
_: &mut FutureBasic,
cx: &mut Context<'_>,
) -> Poll<ControlFlow<Self::Break, Self::Cont>> {
self.poll(cx).map(ControlFlow::Break)
}
fn transform_cont(
_: BorrowedMut<'_, Self>,
_: &mut FutureBasic,
_: Self::Cont,
) -> Option<Self::Output> {
unreachable!("cannot construct std::convert::Infallible")
}
fn transform_break(
_: Removed<F>,
_: &mut FutureBasic,
value: Self::Break,
) -> Option<Self::Output> {
Some(value)
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct FutureReclaim;
impl<F: Future> Task<FutureReclaim> for F {
type Cont = Infallible;
type Break = F::Output;
type Output = (Removed<F>, F::Output);
fn poll_progress(
self: Pin<&mut Self>,
_: &mut FutureReclaim,
cx: &mut Context<'_>,
) -> Poll<ControlFlow<Self::Break, Self::Cont>> {
self.poll(cx).map(ControlFlow::Break)
}
fn transform_cont(
_: BorrowedMut<'_, F>,
_: &mut FutureReclaim,
_: Self::Cont,
) -> Option<Self::Output> {
unreachable!("cannot construct std::convert::Infallible")
}
fn transform_break(
task: Removed<F>,
_: &mut FutureReclaim,
value: Self::Break,
) -> Option<Self::Output> {
Some((task, value))
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct StreamBasic;
impl<S: Stream> Task<StreamBasic> for S {
type Cont = S::Item;
type Break = ();
type Output = S::Item;
fn poll_progress(
self: Pin<&mut Self>,
_: &mut StreamBasic,
cx: &mut Context<'_>,
) -> Poll<ControlFlow<Self::Break, Self::Cont>> {
match std::task::ready!(self.poll_next(cx)) {
Some(item) => Poll::Ready(ControlFlow::Continue(item)),
None => Poll::Ready(ControlFlow::Break(())),
}
}
fn transform_cont(
_: BorrowedMut<'_, Self>,
_: &mut StreamBasic,
value: Self::Cont,
) -> Option<Self::Output> {
Some(value)
}
fn transform_break(
_: Removed<Self>,
_: &mut StreamBasic,
_: Self::Break,
) -> Option<Self::Output> {
None
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct StreamWithId;
impl<S: Stream> Task<StreamWithId> for S {
type Cont = S::Item;
type Break = ();
type Output = (Id<S>, S::Item);
fn poll_progress(
self: Pin<&mut Self>,
_: &mut StreamWithId,
cx: &mut Context<'_>,
) -> Poll<ControlFlow<Self::Break, Self::Cont>> {
match std::task::ready!(self.poll_next(cx)) {
Some(item) => Poll::Ready(ControlFlow::Continue(item)),
None => Poll::Ready(ControlFlow::Break(())),
}
}
fn transform_cont(
task: BorrowedMut<'_, Self>,
_: &mut StreamWithId,
value: Self::Cont,
) -> Option<Self::Output> {
Some((task.id().clone(), value))
}
fn transform_break(
_: Removed<Self>,
_: &mut StreamWithId,
_: Self::Break,
) -> Option<Self::Output> {
None
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct StreamReclaim;
impl<S: Stream> Task<StreamReclaim> for S {
type Cont = S::Item;
type Break = ();
type Output = ControlFlow<Removed<S>, (Id<S>, S::Item)>;
fn poll_progress(
self: Pin<&mut Self>,
_: &mut StreamReclaim,
cx: &mut Context<'_>,
) -> Poll<ControlFlow<Self::Break, Self::Cont>> {
match std::task::ready!(self.poll_next(cx)) {
Some(item) => Poll::Ready(ControlFlow::Continue(item)),
None => Poll::Ready(ControlFlow::Break(())),
}
}
fn transform_cont(
task: BorrowedMut<'_, Self>,
_: &mut StreamReclaim,
value: Self::Cont,
) -> Option<Self::Output> {
Some(ControlFlow::Continue((task.id().clone(), value)))
}
fn transform_break(
task: Removed<Self>,
_: &mut StreamReclaim,
_: Self::Break,
) -> Option<Self::Output> {
Some(ControlFlow::Break(task))
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct TryStreamBasic;
impl<S: TryStream> Task<TryStreamBasic> for S {
type Cont = S::Ok;
type Break = Result<(), S::Error>;
type Output = Result<S::Ok, S::Error>;
fn poll_progress(
self: Pin<&mut Self>,
_: &mut TryStreamBasic,
cx: &mut Context<'_>,
) -> Poll<ControlFlow<Self::Break, Self::Cont>> {
match std::task::ready!(self.try_poll_next(cx)) {
Some(Ok(item)) => Poll::Ready(ControlFlow::Continue(item)),
Some(Err(error)) => Poll::Ready(ControlFlow::Break(Err(error))),
None => Poll::Ready(ControlFlow::Break(Ok(()))),
}
}
fn transform_cont(
_: BorrowedMut<'_, Self>,
_: &mut TryStreamBasic,
value: Self::Cont,
) -> Option<Self::Output> {
Some(Ok(value))
}
fn transform_break(
_: Removed<Self>,
_: &mut TryStreamBasic,
value: Self::Break,
) -> Option<Self::Output> {
value.err().map(Err)
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct TryStreamWithId;
impl<S: TryStream> Task<TryStreamWithId> for S {
type Cont = S::Ok;
type Break = Result<(), S::Error>;
type Output = (Id<S>, Result<S::Ok, S::Error>);
fn poll_progress(
self: Pin<&mut Self>,
_: &mut TryStreamWithId,
cx: &mut Context<'_>,
) -> Poll<ControlFlow<Self::Break, Self::Cont>> {
match std::task::ready!(self.try_poll_next(cx)) {
Some(Ok(item)) => Poll::Ready(ControlFlow::Continue(item)),
Some(Err(error)) => Poll::Ready(ControlFlow::Break(Err(error))),
None => Poll::Ready(ControlFlow::Break(Ok(()))),
}
}
fn transform_cont(
task: BorrowedMut<'_, Self>,
_: &mut TryStreamWithId,
value: Self::Cont,
) -> Option<Self::Output> {
Some((task.id().clone(), Ok(value)))
}
fn transform_break(
task: Removed<Self>,
_: &mut TryStreamWithId,
value: Self::Break,
) -> Option<Self::Output> {
match value {
Ok(()) => None,
Err(error) => Some((task.id().clone(), Err(error))),
}
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct TryStreamReclaim;
impl<S: TryStream> Task<TryStreamReclaim> for S {
type Cont = S::Ok;
type Break = Result<(), S::Error>;
type Output = ControlFlow<(Removed<S>, Result<(), S::Error>), (Id<S>, S::Ok)>;
fn poll_progress(
self: Pin<&mut Self>,
_: &mut TryStreamReclaim,
cx: &mut Context<'_>,
) -> Poll<ControlFlow<Self::Break, Self::Cont>> {
match std::task::ready!(self.try_poll_next(cx)) {
Some(Ok(item)) => Poll::Ready(ControlFlow::Continue(item)),
Some(Err(error)) => Poll::Ready(ControlFlow::Break(Err(error))),
None => Poll::Ready(ControlFlow::Break(Ok(()))),
}
}
fn transform_cont(
task: BorrowedMut<'_, Self>,
_: &mut TryStreamReclaim,
value: Self::Cont,
) -> Option<Self::Output> {
Some(ControlFlow::Continue((task.id().clone(), value)))
}
fn transform_break(
task: Removed<Self>,
_: &mut TryStreamReclaim,
value: Self::Break,
) -> Option<Self::Output> {
Some(ControlFlow::Break((task, value)))
}
}