1use smol::prelude::*;
2use std::{
3 pin::Pin,
4 task::Poll,
5 time::{Duration, Instant},
6};
7
8pub struct Repeat {
9 timer: smol::Timer,
10 period: Duration,
11}
12
13impl Stream for Repeat {
14 type Item = Instant;
15
16 fn poll_next(
17 mut self: std::pin::Pin<&mut Self>,
18 cx: &mut std::task::Context<'_>,
19 ) -> Poll<Option<Self::Item>> {
20 match self.as_mut().timer().poll(cx) {
21 Poll::Ready(instant) => {
22 let period = self.as_ref().period;
23 self.as_mut().timer().set_after(period);
24 Poll::Ready(Some(instant))
25 }
26 Poll::Pending => Poll::Pending,
27 }
28 }
29}
30
31impl Repeat {
32 fn timer(self: std::pin::Pin<&mut Self>) -> Pin<&mut smol::Timer> {
33 unsafe { self.map_unchecked_mut(|s| &mut s.timer) }
34 }
35}
36
37pub fn repeat(period: Duration) -> Repeat {
38 Repeat {
39 timer: smol::Timer::after(period),
40 period,
41 }
42}