clock.rs

 1use chrono::{DateTime, Utc};
 2use parking_lot::Mutex;
 3use std::time::Duration;
 4
 5pub use web_time::Instant;
 6
 7pub trait Clock {
 8    fn utc_now(&self) -> DateTime<Utc>;
 9    fn now(&self) -> Instant;
10}
11
12pub struct TestClock(Mutex<TestClockState>);
13
14struct TestClockState {
15    now: Instant,
16    utc_now: DateTime<Utc>,
17}
18
19impl TestClock {
20    pub fn new() -> Self {
21        const START_TIME: &str = "2025-07-01T23:59:58-00:00";
22        let utc_now = DateTime::parse_from_rfc3339(START_TIME).unwrap().to_utc();
23        Self(Mutex::new(TestClockState {
24            now: Instant::now(),
25            utc_now,
26        }))
27    }
28
29    pub fn set_utc_now(&self, now: DateTime<Utc>) {
30        let mut state = self.0.lock();
31        state.utc_now = now;
32    }
33
34    pub fn advance(&self, duration: Duration) {
35        let mut state = self.0.lock();
36        state.now += duration;
37        state.utc_now += duration;
38    }
39}
40
41impl Clock for TestClock {
42    fn utc_now(&self) -> DateTime<Utc> {
43        self.0.lock().utc_now
44    }
45
46    fn now(&self) -> Instant {
47        self.0.lock().now
48    }
49}