1use core::future::Future;
4use core::{task, time};
5use core::pin::Pin;
6
7use crate::oneshot::Oneshot;
8use crate::oneshot::Timer as PlatformTimer;
9
10#[must_use = "Interval does nothing unless polled"]
33pub struct Interval<T=PlatformTimer> {
34 timer: T,
35 pub interval: time::Duration,
37}
38
39impl Interval {
40 #[inline(always)]
41 pub fn platform_new(interval: time::Duration) -> Self {
43 Interval::<PlatformTimer>::new(interval)
44 }
45}
46
47impl<T: Oneshot> Interval<T> {
48 pub fn new(interval: time::Duration) -> Self {
50 Self {
51 timer: T::new(interval),
52 interval,
53 }
54 }
55
56 #[inline(always)]
57 pub fn cancel(&mut self) {
59 self.timer.cancel()
60 }
61
62 pub fn restart(&mut self, ctx: &task::Context) {
64 let interval = self.interval;
65 self.timer.restart(interval, ctx.waker());
66 }
67
68
69 #[inline(always)]
70 pub fn as_mut(&mut self) -> &mut Self {
72 self
73 }
74}
75
76impl<T: Oneshot> Future for &'_ mut Interval<T> {
77 type Output = ();
78
79 fn poll(mut self: Pin<&mut Self>, ctx: &mut task::Context) -> task::Poll<Self::Output> {
80 match Future::poll(Pin::new(&mut self.timer), ctx) {
81 task::Poll::Ready(()) => {
82 self.restart(ctx);
83 task::Poll::Ready(())
84 },
85 task::Poll::Pending => task::Poll::Pending,
86 }
87 }
88}
89
90#[cfg(feature = "stream")]
91impl<T: Oneshot> futures_core::stream::Stream for Interval<T> {
92 type Item = ();
93
94 #[inline]
95 fn poll_next(self: Pin<&mut Self>, ctx: &mut task::Context) -> task::Poll<Option<Self::Item>> {
96 let mut this = self.get_mut();
97 Future::poll(Pin::new(&mut this), ctx).map(|res| Some(res))
98 }
99}