tokio_timer/
interval.rs

1use Delay;
2
3use clock;
4
5use futures::{Future, Poll, Stream};
6
7use std::time::{Duration, Instant};
8
9/// A stream representing notifications at fixed interval
10#[derive(Debug)]
11pub struct Interval {
12    /// Future that completes the next time the `Interval` yields a value.
13    delay: Delay,
14
15    /// The duration between values yielded by `Interval`.
16    duration: Duration,
17}
18
19impl Interval {
20    /// Create a new `Interval` that starts at `at` and yields every `duration`
21    /// interval after that.
22    ///
23    /// Note that when it starts, it produces item too.
24    ///
25    /// The `duration` argument must be a non-zero duration.
26    ///
27    /// # Panics
28    ///
29    /// This function panics if `duration` is zero.
30    pub fn new(at: Instant, duration: Duration) -> Interval {
31        assert!(
32            duration > Duration::new(0, 0),
33            "`duration` must be non-zero."
34        );
35
36        Interval::new_with_delay(Delay::new(at), duration)
37    }
38
39    /// Creates new `Interval` that yields with interval of `duration`.
40    ///
41    /// The function is shortcut for `Interval::new(Instant::now() + duration, duration)`.
42    ///
43    /// The `duration` argument must be a non-zero duration.
44    ///
45    /// # Panics
46    ///
47    /// This function panics if `duration` is zero.
48    pub fn new_interval(duration: Duration) -> Interval {
49        Interval::new(clock::now() + duration, duration)
50    }
51
52    pub(crate) fn new_with_delay(delay: Delay, duration: Duration) -> Interval {
53        Interval { delay, duration }
54    }
55}
56
57impl Stream for Interval {
58    type Item = Instant;
59    type Error = ::Error;
60
61    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
62        // Wait for the delay to be done
63        let _ = try_ready!(self.delay.poll());
64
65        // Get the `now` by looking at the `delay` deadline
66        let now = self.delay.deadline();
67
68        // The next interval value is `duration` after the one that just
69        // yielded.
70        self.delay.reset(now + self.duration);
71
72        // Return the current instant
73        Ok(Some(now).into())
74    }
75}