1use std::sync::atomic::{AtomicU64, Ordering};
2
3pub trait Clock: Send + Sync {
8 fn now_micros(&self) -> u64;
10}
11
12#[derive(Debug, Clone, Copy, Default)]
14pub struct SystemClock;
15
16impl Clock for SystemClock {
17 fn now_micros(&self) -> u64 {
18 iggy::prelude::IggyTimestamp::now().as_micros()
19 }
20}
21
22#[derive(Debug, Default)]
25pub struct TestClock {
26 now_micros: AtomicU64,
27}
28
29impl TestClock {
30 pub fn new(start_micros: u64) -> Self {
32 Self {
33 now_micros: AtomicU64::new(start_micros),
34 }
35 }
36
37 pub fn advance(&self, by_micros: u64) {
39 self.now_micros.fetch_add(by_micros, Ordering::Relaxed);
40 }
41
42 pub fn set(&self, now_micros: u64) {
44 self.now_micros.store(now_micros, Ordering::Relaxed);
45 }
46}
47
48impl Clock for TestClock {
49 fn now_micros(&self) -> u64 {
50 self.now_micros.load(Ordering::Relaxed)
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn given_a_test_clock_when_advanced_then_should_report_the_set_time() {
60 let clock = TestClock::new(1_000);
61 assert_eq!(clock.now_micros(), 1_000);
62 clock.advance(500);
63 assert_eq!(clock.now_micros(), 1_500);
64 clock.set(42);
65 assert_eq!(clock.now_micros(), 42);
66 }
67}