local_clock/
clock_impls.rs1use super::LocalClock;
7use super::LocalClockDelta;
8use super::LocalClockTime;
9use parking_lot::Mutex;
10use std::sync::Arc;
11use std::time::SystemTime;
12
13#[derive(Debug)]
29#[cfg_attr(feature = "inspect", derive(inspect::Inspect))]
30pub struct SystemTimeClock {
31 offset_from_system_time: LocalClockDelta,
32}
33
34impl SystemTimeClock {
35 pub fn new(initial_delta: LocalClockDelta) -> SystemTimeClock {
38 SystemTimeClock {
39 offset_from_system_time: initial_delta,
40 }
41 }
42}
43
44impl LocalClock for SystemTimeClock {
45 fn get_time(&mut self) -> LocalClockTime {
46 LocalClockTime::from(SystemTime::now()) + self.offset_from_system_time
47 }
48
49 fn set_time(&mut self, new_time: LocalClockTime) {
50 self.offset_from_system_time = new_time - LocalClockTime::from(SystemTime::now());
51 }
52}
53
54#[derive(Debug)]
57#[cfg_attr(feature = "inspect", derive(inspect::Inspect))]
58pub struct MockLocalClock {
59 time: Arc<Mutex<LocalClockTime>>,
60}
61
62impl MockLocalClock {
63 pub fn new() -> Self {
65 MockLocalClock {
66 time: Arc::new(Mutex::new(LocalClockTime::from_millis_since_unix_epoch(
67 1337,
68 ))),
69 }
70 }
71
72 pub fn accessor(&self) -> MockLocalClockAccessor {
74 MockLocalClockAccessor {
75 time: self.time.clone(),
76 }
77 }
78}
79
80impl LocalClock for MockLocalClock {
81 fn get_time(&mut self) -> LocalClockTime {
82 *self.time.lock()
83 }
84
85 fn set_time(&mut self, new_time: LocalClockTime) {
86 *self.time.lock() = new_time
87 }
88}
89
90#[derive(Clone)]
92pub struct MockLocalClockAccessor {
93 time: Arc<Mutex<LocalClockTime>>,
94}
95
96impl MockLocalClockAccessor {
97 pub fn tick(&self, d: std::time::Duration) {
99 let mut time = self.time.lock();
100 *time = *time + LocalClockDelta::from_millis(d.as_millis().try_into().unwrap())
101 }
102
103 pub fn tick_backwards(&self, d: std::time::Duration) {
105 let mut time = self.time.lock();
106 *time = *time - LocalClockDelta::from_millis(d.as_millis().try_into().unwrap())
107 }
108
109 pub fn get_time(&self) -> LocalClockTime {
111 *self.time.lock()
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn naive_system_time() {
121 let mut clock = SystemTimeClock::new(LocalClockDelta::ZERO);
122
123 let time = clock.get_time();
124 std::thread::sleep(std::time::Duration::from_secs(1));
125 let new_time = clock.get_time();
126
127 let delta = new_time - time;
128
129 assert!(delta >= std::time::Duration::from_secs(1).into());
132 assert!(delta < std::time::Duration::from_secs(2).into()); }
134
135 #[test]
136 fn initial_delta() {
137 let mut clock = SystemTimeClock::new(LocalClockDelta::from_millis(1000));
138
139 let time = clock.get_time();
140 let now = LocalClockTime::from(SystemTime::now());
141
142 let delta = time - now;
143
144 assert!(delta >= LocalClockDelta::from_millis(1000));
147 assert!(delta < LocalClockDelta::from_millis(2000)); }
149
150 #[test]
151 fn naive_set_time_backwards() {
152 let mut clock = SystemTimeClock::new(LocalClockDelta::ZERO);
153
154 clock.set_time(LocalClockTime::from_millis_since_unix_epoch(0));
155
156 let time = clock.get_time();
157 std::thread::sleep(std::time::Duration::from_secs(1));
158 let new_time = clock.get_time();
159
160 let delta = new_time - time;
161
162 assert!(delta >= std::time::Duration::from_secs(1).into());
165 assert!(delta < std::time::Duration::from_secs(2).into()); }
167}