async_std/stream/interval.rs
1use std::future::Future;
2use std::pin::Pin;
3use std::task::{Context, Poll};
4use std::time::Duration;
5
6use crate::stream::Stream;
7use crate::utils::{timer_after, Timer};
8
9/// Creates a new stream that yields at a set interval.
10///
11/// The stream first yields after `dur`, and continues to yield every
12/// `dur` after that. The stream accounts for time elapsed between calls, and
13/// will adjust accordingly to prevent time skews.
14///
15/// Each interval may be slightly longer than the specified duration, but never
16/// less.
17///
18/// Note that intervals are not intended for high resolution timers, but rather
19/// they will likely fire some granularity after the exact instant that they're
20/// otherwise indicated to fire at.
21///
22/// See also: [`task::sleep`].
23///
24/// [`task::sleep`]: ../task/fn.sleep.html
25///
26/// # Examples
27///
28/// Basic example:
29///
30/// ```no_run
31/// use async_std::prelude::*;
32/// use async_std::stream;
33/// use std::time::Duration;
34///
35/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
36/// #
37/// let mut interval = stream::interval(Duration::from_secs(4));
38/// while let Some(_) = interval.next().await {
39/// println!("prints every four seconds");
40/// }
41/// #
42/// # Ok(()) }) }
43/// ```
44#[cfg(feature = "unstable")]
45#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
46pub fn interval(dur: Duration) -> Interval {
47 Interval {
48 delay: timer_after(dur),
49 interval: dur,
50 }
51}
52
53/// A stream representing notifications at fixed interval
54///
55/// This stream is created by the [`interval`] function. See its
56/// documentation for more.
57///
58/// [`interval`]: fn.interval.html
59#[cfg(feature = "unstable")]
60#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
61#[derive(Debug)]
62pub struct Interval {
63 delay: Timer,
64 interval: Duration,
65}
66
67impl Stream for Interval {
68 type Item = ();
69
70 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
71 if Pin::new(&mut self.delay).poll(cx).is_pending() {
72 return Poll::Pending;
73 }
74 let interval = self.interval;
75 let _ = std::mem::replace(&mut self.delay, timer_after(interval));
76 Poll::Ready(Some(()))
77 }
78}