use core::future::Future;
use core::{task, time};
use core::pin::Pin;
use crate::oneshot::Oneshot;
use crate::oneshot::Timer as PlatformTimer;
#[must_use = "Interval does nothing unless polled"]
pub struct Interval<T=PlatformTimer> {
timer: T,
pub interval: time::Duration,
}
impl Interval {
#[inline(always)]
pub fn platform_new(interval: time::Duration) -> Self {
Interval::<PlatformTimer>::new(interval)
}
}
impl<T: Oneshot> Interval<T> {
pub fn new(interval: time::Duration) -> Self {
Self {
timer: T::new(interval),
interval,
}
}
#[inline(always)]
pub fn cancel(&mut self) {
self.timer.cancel()
}
pub fn restart(&mut self, ctx: &task::Context) {
let interval = self.interval;
self.timer.restart(interval, ctx.waker());
}
#[inline(always)]
pub fn as_mut(&mut self) -> &mut Self {
self
}
}
impl<T: Oneshot> Future for &'_ mut Interval<T> {
type Output = ();
fn poll(mut self: Pin<&mut Self>, ctx: &mut task::Context) -> task::Poll<Self::Output> {
match Future::poll(Pin::new(&mut self.timer), ctx) {
task::Poll::Ready(()) => {
self.restart(ctx);
task::Poll::Ready(())
},
task::Poll::Pending => task::Poll::Pending,
}
}
}
#[cfg(feature = "stream")]
impl<T: Oneshot> futures_core::stream::Stream for Interval<T> {
type Item = ();
#[inline]
fn poll_next(self: Pin<&mut Self>, ctx: &mut task::Context) -> task::Poll<Option<Self::Item>> {
let mut this = self.get_mut();
Future::poll(Pin::new(&mut this), ctx).map(|res| Some(res))
}
}