1use std::sync::atomic::{AtomicU64, Ordering};
2use std::time::{SystemTime, UNIX_EPOCH};
3
4pub trait Clock: Send + Sync {
5 fn now_epoch_s(&self) -> u64;
6}
7
8#[derive(Debug, Default)]
9pub struct SystemClock;
10
11impl Clock for SystemClock {
12 fn now_epoch_s(&self) -> u64 {
13 SystemTime::now()
14 .duration_since(UNIX_EPOCH)
15 .map_or(0, |duration| duration.as_secs())
16 }
17}
18
19#[derive(Debug)]
20pub struct FixedClock {
21 now_epoch_s: AtomicU64,
22}
23
24impl FixedClock {
25 #[must_use]
26 pub fn new(now_epoch_s: u64) -> Self {
27 Self {
28 now_epoch_s: AtomicU64::new(now_epoch_s),
29 }
30 }
31
32 pub fn set(&self, now_epoch_s: u64) {
33 self.now_epoch_s.store(now_epoch_s, Ordering::Relaxed);
34 }
35
36 pub fn advance_by(&self, delta_s: u64) {
37 self.now_epoch_s.fetch_add(delta_s, Ordering::Relaxed);
38 }
39}
40
41impl Clock for FixedClock {
42 fn now_epoch_s(&self) -> u64 {
43 self.now_epoch_s.load(Ordering::Relaxed)
44 }
45}