1use std::fmt::Debug;
8use std::sync::Arc;
9use std::time::{Duration, SystemTime, UNIX_EPOCH};
10
11pub trait TimeSource: Debug + Send + Sync {
13 fn now(&self) -> SystemTime;
15}
16
17#[non_exhaustive]
19#[derive(Debug, Default)]
20pub struct SystemTimeSource;
21
22impl SystemTimeSource {
23 pub fn new() -> Self {
25 SystemTimeSource
26 }
27}
28
29impl TimeSource for SystemTimeSource {
30 fn now(&self) -> SystemTime {
31 #[allow(clippy::disallowed_methods)]
33 SystemTime::now()
34 }
35}
36
37impl Default for SharedTimeSource {
38 fn default() -> Self {
39 SharedTimeSource(Arc::new(SystemTimeSource))
40 }
41}
42
43#[derive(Debug)]
45pub struct StaticTimeSource {
46 time: SystemTime,
47}
48
49impl StaticTimeSource {
50 pub fn new(time: SystemTime) -> Self {
52 Self { time }
53 }
54
55 pub fn from_secs(epoch_secs: u64) -> Self {
57 Self::new(UNIX_EPOCH + Duration::from_secs(epoch_secs))
58 }
59}
60
61impl TimeSource for StaticTimeSource {
62 fn now(&self) -> SystemTime {
63 self.time
64 }
65}
66
67impl From<StaticTimeSource> for SharedTimeSource {
68 fn from(value: StaticTimeSource) -> Self {
69 SharedTimeSource::new(value)
70 }
71}
72
73#[derive(Debug, Clone)]
74pub struct SharedTimeSource(Arc<dyn TimeSource>);
78
79impl SharedTimeSource {
80 pub fn now(&self) -> SystemTime {
82 self.0.now()
83 }
84
85 pub fn new(source: impl TimeSource + 'static) -> Self {
87 Self(Arc::new(source))
88 }
89}
90
91impl TimeSource for SharedTimeSource {
92 fn now(&self) -> SystemTime {
93 self.0.now()
94 }
95}