Skip to main content

wreq_proto/rt/
timer.rs

1//! Provides a timer trait with timer-like functions
2
3use std::{
4    future::Future,
5    pin::Pin,
6    sync::Arc,
7    time::{Duration, Instant},
8};
9
10/// A timer which provides timer-like functions.
11pub trait Timer {
12    /// Return a future that resolves in `duration` time.
13    fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>>;
14
15    /// Return a future that resolves at `deadline`.
16    fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn Sleep>>;
17
18    /// Return an `Instant` representing the current time.
19    ///
20    /// The default implementation returns [`Instant::now()`].
21    fn now(&self) -> Instant {
22        Instant::now()
23    }
24
25    /// Reset a future to resolve at `new_deadline` instead.
26    fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
27        *sleep = self.sleep_until(new_deadline);
28    }
29}
30
31/// A future returned by a `Timer`.
32pub trait Sleep: Send + Sync + Future<Output = ()> {
33    /// Reset the future to resolve at `new_deadline` instead.
34    fn reset(self: Pin<&mut Self>, new_deadline: Instant);
35}
36
37/// A user-provided timer to time background tasks.
38#[derive(Clone)]
39pub enum Time {
40    /// A user-provided timer.
41    Timer(Arc<dyn Timer + Send + Sync>),
42    /// No timer provided.
43    Empty,
44}
45
46// ===== impl Time =====
47
48impl Timer for Time {
49    fn sleep(&self, duration: Duration) -> Pin<Box<dyn Sleep>> {
50        match *self {
51            Time::Empty => {
52                panic!("You must supply a timer.")
53            }
54            Time::Timer(ref t) => t.sleep(duration),
55        }
56    }
57
58    fn now(&self) -> Instant {
59        match *self {
60            Time::Empty => Instant::now(),
61            Time::Timer(ref t) => t.now(),
62        }
63    }
64
65    fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn Sleep>> {
66        match *self {
67            Time::Empty => {
68                panic!("You must supply a timer.")
69            }
70            Time::Timer(ref t) => t.sleep_until(deadline),
71        }
72    }
73
74    fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: Instant) {
75        match *self {
76            Time::Empty => {
77                panic!("You must supply a timer.")
78            }
79            Time::Timer(ref t) => t.reset(sleep, new_deadline),
80        }
81    }
82}