use core::future::Future;
use core::pin::Pin;
use core::task::{Context, Poll};
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
pub struct Yield(bool);
#[doc(hidden)]
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
pub struct YieldWhile<F: FnMut() -> bool>(F);
#[doc(hidden)]
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
pub struct YieldTimes { pub remaining: usize }
impl Yield {
pub fn once() -> Self { Self(false) }
pub fn none() -> Self { Self(true) }
pub fn times(remaining: usize) -> YieldTimes { YieldTimes { remaining } }
pub fn yield_while<F>(predicate: F) -> YieldWhile<F> where F: FnMut() -> bool {
YieldWhile(predicate)
}
}
impl Future for Yield {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if self.0 { Poll::Ready(()) } else {
self.get_mut().0 = true;
cx.waker().wake_by_ref();
Poll::Pending
}
}
}
impl<F: FnMut() -> bool> Future for YieldWhile<F> {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let func = unsafe{ &mut self.get_unchecked_mut().0 };
if !func() { Poll::Ready(()) } else {
cx.waker().wake_by_ref();
Poll::Pending
}
}
}
impl Future for YieldTimes {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if self.remaining == 0 { Poll::Ready(()) } else {
self.as_mut().remaining -= 1;
cx.waker().wake_by_ref();
Poll::Pending
}
}
}