#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "alloc")]
extern crate alloc;
use core::future::Future as RegularFuture;
#[cfg(doc)]
use core::future::Future;
use core::ops::DerefMut;
use core::pin::Pin;
use core::task::{Context, Poll};
#[cfg(doc)]
use futures_core::Stream;
#[must_use = "futures do nothing unless you use them"]
pub trait CompletionFuture {
type Output;
unsafe fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
unsafe fn poll_cancel(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()>;
}
impl<F: CompletionFuture + Unpin + ?Sized> CompletionFuture for &'_ mut F {
type Output = F::Output;
unsafe fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut **self).poll(cx)
}
unsafe fn poll_cancel(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
Pin::new(&mut **self).poll_cancel(cx)
}
}
#[cfg(feature = "alloc")]
impl<F: CompletionFuture + Unpin + ?Sized> CompletionFuture for alloc::boxed::Box<F> {
type Output = F::Output;
unsafe fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut **self).poll(cx)
}
unsafe fn poll_cancel(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
Pin::new(&mut **self).poll_cancel(cx)
}
}
impl<P> CompletionFuture for Pin<P>
where
P: Unpin + DerefMut,
P::Target: CompletionFuture,
{
type Output = <P::Target as CompletionFuture>::Output;
unsafe fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.get_mut().as_mut().poll(cx)
}
unsafe fn poll_cancel(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
self.get_mut().as_mut().poll_cancel(cx)
}
}
#[cfg(feature = "std")]
impl<F: CompletionFuture> CompletionFuture for std::panic::AssertUnwindSafe<F> {
type Output = F::Output;
unsafe fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::map_unchecked_mut(self, |this| &mut this.0).poll(cx)
}
unsafe fn poll_cancel(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
Pin::map_unchecked_mut(self, |this| &mut this.0).poll_cancel(cx)
}
}
macro_rules! derive_completion_future {
($([$($generics:tt)*] $t:ty,)*) => {
$(
impl<$($generics)*> CompletionFuture for $t
where
Self: RegularFuture,
{
type Output = <$t as RegularFuture>::Output;
unsafe fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
RegularFuture::poll(self, cx)
}
unsafe fn poll_cancel(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<()> {
Poll::Ready(())
}
}
)*
};
}
derive_completion_future! {
[T] core::future::Pending<T>,
[T] core::future::Ready<T>,
}
#[must_use = "streams do nothing unless you use them"]
pub trait CompletionStream {
type Item;
unsafe fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
unsafe fn poll_cancel(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()>;
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
impl<S: CompletionStream + Unpin + ?Sized> CompletionStream for &'_ mut S {
type Item = S::Item;
unsafe fn poll_next(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Self::Item>> {
Pin::new(&mut **self).poll_next(cx)
}
unsafe fn poll_cancel(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
Pin::new(&mut **self).poll_cancel(cx)
}
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
#[cfg(feature = "alloc")]
impl<S: CompletionStream + Unpin + ?Sized> CompletionStream for alloc::boxed::Box<S> {
type Item = S::Item;
unsafe fn poll_next(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Self::Item>> {
Pin::new(&mut **self).poll_next(cx)
}
unsafe fn poll_cancel(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
Pin::new(&mut **self).poll_cancel(cx)
}
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
impl<P> CompletionStream for Pin<P>
where
P: Unpin + DerefMut,
P::Target: CompletionStream,
{
type Item = <P::Target as CompletionStream>::Item;
unsafe fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
self.get_mut().as_mut().poll_next(cx)
}
unsafe fn poll_cancel(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
self.get_mut().as_mut().poll_cancel(cx)
}
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
#[cfg(feature = "std")]
impl<S: CompletionStream> CompletionStream for std::panic::AssertUnwindSafe<S> {
type Item = S::Item;
unsafe fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Pin::map_unchecked_mut(self, |this| &mut this.0).poll_next(cx)
}
unsafe fn poll_cancel(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
Pin::map_unchecked_mut(self, |this| &mut this.0).poll_cancel(cx)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}