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