use crate::prelude::*;
pub trait Notifier {
type Event;
fn poll_next(self: Pin<&mut Self>, t: &mut Task<'_>) -> Poll<Self::Event>;
#[inline]
fn next(&mut self) -> EventFuture<'_, Self>
where
Self: Sized + Unpin,
{
EventFuture(self)
}
fn map<B, F>(self, f: F) -> Map<Self, F>
where
Self: Sized + Unpin,
{
let noti = self;
Map { noti, f }
}
}
impl<N: ?Sized + Notifier + Unpin> Notifier for Box<N> {
type Event = N::Event;
#[inline]
fn poll_next(self: Pin<&mut Self>, t: &mut Task<'_>) -> Poll<N::Event> {
Pin::new(self.get_mut().as_mut()).poll_next(t)
}
}
impl<N: Notifier + ?Sized, P> Notifier for Pin<P>
where
P: core::ops::DerefMut<Target = N> + Unpin,
{
type Event = N::Event;
fn poll_next(self: Pin<&mut Self>, t: &mut Task<'_>) -> Poll<Self::Event> {
Pin::get_mut(self).as_mut().poll_next(t)
}
}
impl<N: Notifier + Unpin + ?Sized> Notifier for &mut N {
type Event = N::Event;
#[inline]
fn poll_next(mut self: Pin<&mut Self>, t: &mut Task<'_>) -> Poll<N::Event> {
Pin::new(&mut **self).poll_next(t)
}
}
impl<N: Notifier + Unpin> Notifier for [N] {
type Event = (usize, N::Event);
#[inline]
fn poll_next(self: Pin<&mut Self>, t: &mut Task<'_>) -> Poll<Self::Event> {
for (i, this) in self.get_mut().iter_mut().enumerate() {
if let Ready(value) = Pin::new(this).poll_next(t) {
return Ready((i, value));
}
}
Pending
}
}
#[derive(Debug)]
pub struct EventFuture<'a, N: Notifier + Unpin>(&'a mut N);
impl<N: Notifier + Unpin> Future for EventFuture<'_, N> {
type Output = N::Event;
#[inline]
fn poll(self: Pin<&mut Self>, t: &mut Task<'_>) -> Poll<Self::Output> {
Pin::new(&mut self.get_mut().0).poll_next(t)
}
}
#[derive(Debug)]
pub struct Poller<T, F: FnMut(&mut Task<'_>) -> Poll<T> + Unpin>(F);
impl<T, F: FnMut(&mut Task<'_>) -> Poll<T> + Unpin> Poller<T, F> {
pub fn new(f: F) -> Self {
Self(f)
}
}
impl<T, F: FnMut(&mut Task<'_>) -> Poll<T> + Unpin> Notifier for Poller<T, F> {
type Event = T;
#[inline]
fn poll_next(self: Pin<&mut Self>, t: &mut Task<'_>) -> Poll<T> {
self.get_mut().0(t)
}
}
pub trait Fuse: Sized {
fn fuse(self) -> Option<Self>;
}
impl<F: Future> Fuse for F {
fn fuse(self) -> Option<Self> {
self.into()
}
}
impl<F: Future> Notifier for Option<F> {
type Event = F::Output;
#[inline]
fn poll_next(self: Pin<&mut Self>, t: &mut Task<'_>) -> Poll<F::Output> {
let mut s = self;
let out = s.as_mut().as_pin_mut().map(|f| f.poll(t));
if matches!(out, Some(Ready(_))) {
s.set(None);
}
out.unwrap_or(Pending)
}
}
pub trait Rep<F: Future>: Unpin {
fn poll(self: Pin<&mut Self>, t: &mut Task<'_>) -> Poll<F::Output>;
fn set(self: Pin<&mut Self>, future: F);
}
impl<F: Future> Rep<F> for Pin<Box<F>> {
#[inline]
fn poll(self: Pin<&mut Self>, t: &mut Task<'_>) -> Poll<F::Output> {
Future::poll(self, t)
}
#[inline]
fn set(self: Pin<&mut Self>, f: F) {
Pin::set(self.get_mut(), f);
}
}
impl<F: Future + Unpin> Rep<F> for F {
#[inline]
fn poll(self: Pin<&mut Self>, t: &mut Task<'_>) -> Poll<F::Output> {
Future::poll(self, t)
}
#[inline]
fn set(mut self: Pin<&mut Self>, f: F) {
*self = f;
}
}
#[derive(Debug)]
pub struct Loop<F: Future, L: FnMut() -> F, S>(S, L);
impl<F: Future + Unpin, L: FnMut() -> F> Loop<F, L, F> {
pub fn new(mut looper: L) -> Self {
Self(looper(), looper)
}
}
impl<F: Future, L: FnMut() -> F> Loop<F, L, Pin<Box<F>>> {
pub fn pin(mut looper: L) -> Self {
Self(Box::pin(looper()), looper)
}
}
impl<F: Future, L: FnMut() -> F + Unpin, S: Rep<F>> Notifier for Loop<F, L, S> {
type Event = F::Output;
#[inline]
fn poll_next(self: Pin<&mut Self>, t: &mut Task<'_>) -> Poll<F::Output> {
let this = self.get_mut();
let poll = Pin::new(&mut this.0).poll(t);
if poll.is_ready() {
Pin::new(&mut this.0).set(this.1());
}
poll
}
}
#[derive(Debug)]
pub struct Map<N, F> {
noti: N,
f: F,
}
impl<N: Notifier + Unpin, F, E> Notifier for Map<N, F>
where
F: FnMut(N::Event) -> E + Unpin,
{
type Event = E;
#[inline]
fn poll_next(mut self: Pin<&mut Self>, t: &mut Task<'_>) -> Poll<E> {
Pin::new(&mut self.noti).poll_next(t).map(&mut self.f)
}
}