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