governor/clock/
with_std.rs1use super::{Clock, Reference};
2
3use std::prelude::v1::*;
4
5use crate::nanos::Nanos;
6use std::ops::Add;
7use std::time::{Duration, SystemTime};
8use web_time::Instant;
9
10#[derive(Clone, Debug, Default)]
12pub struct MonotonicClock;
13
14impl Add<Nanos> for Instant {
15 type Output = Instant;
16
17 fn add(self, other: Nanos) -> Instant {
18 let other: Duration = other.into();
19 self + other
20 }
21}
22
23impl Reference for Instant {
24 fn duration_since(&self, earlier: Self) -> Nanos {
25 if earlier < *self {
26 (*self - earlier).into()
27 } else {
28 Nanos::from(Duration::new(0, 0))
29 }
30 }
31
32 fn saturating_sub(&self, duration: Nanos) -> Self {
33 self.checked_sub(duration.into()).unwrap_or(*self)
34 }
35}
36
37impl Clock for MonotonicClock {
38 type Instant = Instant;
39
40 fn now(&self) -> Self::Instant {
41 Instant::now()
42 }
43}
44
45#[derive(Clone, Debug, Default)]
47pub struct SystemClock;
48
49impl Reference for SystemTime {
50 fn duration_since(&self, earlier: Self) -> Nanos {
55 self.duration_since(earlier)
56 .unwrap_or_else(|_| Duration::new(0, 0))
57 .into()
58 }
59
60 fn saturating_sub(&self, duration: Nanos) -> Self {
61 self.checked_sub(duration.into()).unwrap_or(*self)
62 }
63}
64
65impl Add<Nanos> for SystemTime {
66 type Output = SystemTime;
67
68 fn add(self, other: Nanos) -> SystemTime {
69 let other: Duration = other.into();
70 self + other
71 }
72}
73
74impl Clock for SystemClock {
75 type Instant = SystemTime;
76
77 fn now(&self) -> Self::Instant {
78 SystemTime::now()
79 }
80}
81
82pub trait ReasonablyRealtime: Clock {
87 fn reference_point(&self) -> Self::Instant {
89 self.now()
90 }
91}
92
93impl ReasonablyRealtime for MonotonicClock {}
94
95impl ReasonablyRealtime for SystemClock {}
96
97#[cfg(test)]
101mod test {
102 use super::*;
103 use crate::clock::{Clock, Reference, SystemClock};
104 use crate::nanos::Nanos;
105 use std::time::Duration;
106
107 cfg_if::cfg_if! {
108 if #[cfg(not(all(target_arch = "aarch64", target_os = "macos")))] {
111 use crate::clock::MonotonicClock;
112 #[test]
113 fn instant_impls_coverage() {
114 let one_ns = Nanos::new(1);
115 let c = MonotonicClock::default();
116 let now = c.now();
117 let ns_dur = Duration::from(one_ns);
118 assert_ne!(now + ns_dur, now, "{:?} + {:?}", ns_dur, now);
119 assert_eq!(one_ns, Reference::duration_since(&(now + one_ns), now));
120 assert_eq!(Nanos::new(0), Reference::duration_since(&now, now + one_ns));
121 assert_eq!(
122 Reference::saturating_sub(&(now + Duration::from_nanos(1)), one_ns),
123 now
124 );
125 }
126 }
127 }
128
129 #[test]
130 fn system_clock_impls_coverage() {
131 let one_ns = Nanos::new(1);
132 let c = SystemClock;
133 let now = c.now();
134 assert_ne!(now + one_ns, now);
135 assert_eq!(one_ns, Reference::duration_since(&(now + one_ns), now));
138 assert_eq!(
139 Reference::saturating_sub(&(now + Duration::from_nanos(1)), one_ns),
140 now
141 );
142 }
143}