1pub trait Clock {
9 fn now_ms(&self) -> u64;
11}
12
13#[cfg(feature = "std")]
15#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
16pub struct SystemClock {
17 epoch: std::time::Instant,
18}
19
20#[cfg(feature = "std")]
21impl SystemClock {
22 pub fn new() -> Self {
24 Self {
25 epoch: std::time::Instant::now(),
26 }
27 }
28}
29
30#[cfg(feature = "std")]
31impl Default for SystemClock {
32 fn default() -> Self {
33 Self::new()
34 }
35}
36
37#[cfg(feature = "std")]
38impl Clock for SystemClock {
39 fn now_ms(&self) -> u64 {
40 self.epoch.elapsed().as_millis() as u64
41 }
42}
43
44#[cfg(feature = "alloc")]
50#[derive(Debug, Default, Clone)]
51pub struct MockClock {
52 inner: alloc::sync::Arc<core::sync::atomic::AtomicU64>,
53}
54
55#[cfg(feature = "alloc")]
56impl MockClock {
57 pub fn new() -> Self {
59 Self::default()
60 }
61
62 pub fn advance(&self, ms: u64) {
64 self.inner
65 .fetch_add(ms, core::sync::atomic::Ordering::Relaxed);
66 }
67
68 pub fn set(&self, ms: u64) {
70 self.inner.store(ms, core::sync::atomic::Ordering::Relaxed);
71 }
72}
73
74#[cfg(feature = "alloc")]
75impl Clock for MockClock {
76 fn now_ms(&self) -> u64 {
77 self.inner.load(core::sync::atomic::Ordering::Relaxed)
78 }
79}
80
81impl<C: Clock + ?Sized> Clock for &C {
82 fn now_ms(&self) -> u64 {
83 (*self).now_ms()
84 }
85}