system_clock.rs

 1use std::time::Instant;
 2
 3pub trait SystemClock: Send + Sync {
 4    /// Returns the current date and time in UTC.
 5    fn utc_now(&self) -> Instant;
 6}
 7
 8pub struct RealSystemClock;
 9
10impl SystemClock for RealSystemClock {
11    fn utc_now(&self) -> Instant {
12        Instant::now()
13    }
14}
15
16#[cfg(any(test, feature = "test-support"))]
17pub struct FakeSystemClockState {
18    now: Instant,
19}
20
21#[cfg(any(test, feature = "test-support"))]
22pub struct FakeSystemClock {
23    // Use an unfair lock to ensure tests are deterministic.
24    state: parking_lot::Mutex<FakeSystemClockState>,
25}
26
27#[cfg(any(test, feature = "test-support"))]
28impl FakeSystemClock {
29    pub fn new() -> Self {
30        let state = FakeSystemClockState {
31            now: Instant::now(),
32        };
33
34        Self {
35            state: parking_lot::Mutex::new(state),
36        }
37    }
38
39    pub fn set_now(&self, now: Instant) {
40        self.state.lock().now = now;
41    }
42
43    pub fn advance(&self, duration: std::time::Duration) {
44        self.state.lock().now += duration;
45    }
46}
47
48#[cfg(any(test, feature = "test-support"))]
49impl SystemClock for FakeSystemClock {
50    fn utc_now(&self) -> Instant {
51        self.state.lock().now
52    }
53}