async_time_mock_core/
interval.rs1use crate::{Instant, TimeHandlerGuard, TimerRegistry};
2use std::fmt::{Debug, Formatter};
3use std::future::{poll_fn, Future};
4use std::pin::Pin;
5use std::sync::Arc;
6use std::task::{ready, Context, Poll};
7use std::time::Duration;
8
9pub struct Interval {
10 timer_registry: Arc<TimerRegistry>,
11 sleep: Pin<Box<dyn Future<Output = TimeHandlerGuard> + Send>>,
12 next_deadline: Instant,
13 period: Duration,
14}
15
16impl Interval {
17 pub(crate) fn new(timer_registry: Arc<TimerRegistry>, start: Instant, period: Duration) -> Self {
18 let sleep = Box::pin(timer_registry.sleep_until(start));
19 Self {
20 timer_registry,
21 sleep,
22 next_deadline: start,
23 period,
24 }
25 }
26
27 pub async fn tick(&mut self) -> (TimeHandlerGuard, Instant) {
28 poll_fn(|context| self.poll_tick(context)).await
29 }
30
31 pub fn poll_tick(&mut self, context: &mut Context<'_>) -> Poll<(TimeHandlerGuard, Instant)> {
32 let guard = ready!(self.sleep.as_mut().poll(context));
33
34 let tick_time = self.next_deadline;
35
36 self.next_deadline = tick_time + self.period;
37
38 self.sleep = Box::pin(self.timer_registry.sleep_until(self.next_deadline));
39
40 Poll::Ready((guard, tick_time))
41 }
42
43 pub fn reset(&mut self) {
44 let now = self.timer_registry.now();
45 self.next_deadline = now + self.period;
46 self.sleep = Box::pin(self.timer_registry.sleep_until(self.next_deadline));
47 }
48
49 pub fn period(&self) -> Duration {
50 self.period
51 }
52}
53
54impl Debug for Interval {
55 fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
56 let Self {
57 timer_registry,
58 sleep: _,
59 next_deadline,
60 period,
61 } = self;
62 formatter
63 .debug_struct("Interval")
64 .field("timer_registry", timer_registry)
65 .field("sleep", &"impl Future<Output = TimeHandlerGuard>")
66 .field("next_deadline", next_deadline)
67 .field("period", period)
68 .finish()
69 }
70}