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}