kayrx_timer/
instant.rs

1#![allow(clippy::trivially_copy_pass_by_ref)]
2
3use std::fmt;
4use std::ops;
5use std::time::Duration;
6
7/// A measurement of the system clock, useful for talking to
8/// external entities like the file system or other processes.
9#[derive(Clone, Copy, Eq, PartialEq, PartialOrd)]
10pub struct Instant {
11    std: std::time::Instant,
12}
13
14impl Instant {
15    /// Returns an instant corresponding to "now".
16    ///
17    /// # Examples
18    ///
19    /// ```
20    /// use kayrx_timer::Instant;
21    ///
22    /// let now = Instant::now();
23    /// ```
24    pub fn now() -> Instant {
25        variant::now()
26    }
27
28    /// Create a `kayrx_timer::Instant` from a `std::time::Instant`.
29    pub fn from_std(std: std::time::Instant) -> Instant {
30        Instant { std }
31    }
32
33    /// Convert the value into a `std::time::Instant`.
34    pub fn into_std(self) -> std::time::Instant {
35        self.std
36    }
37
38    /// Returns the amount of time elapsed from another instant to this one.
39    ///
40    /// # Panics
41    ///
42    /// This function will panic if `earlier` is later than `self`.
43    pub fn duration_since(&self, earlier: Instant) -> Duration {
44        self.std.duration_since(earlier.std)
45    }
46
47    /// Returns the amount of time elapsed from another instant to this one, or
48    /// None if that instant is later than this one.
49    ///
50    /// # Examples
51    ///
52    /// ```
53    /// use kayrx_timer::{Duration, Instant, delay_for};
54    /// use kayrx_karx;
55    ///
56    /// fn main() {
57    ///          kayrx_karx::exec(async {
58    ///              let now = Instant::now();
59    ///              delay_for(Duration::new(1, 0)).await;
60    ///              let new_now = Instant::now();
61    ///              println!("{:?}", new_now.checked_duration_since(now));
62    ///              println!("{:?}", now.checked_duration_since(new_now)); // None
63    ///          });
64    /// }
65    /// ```
66    pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
67        self.std.checked_duration_since(earlier.std)
68    }
69
70    /// Returns the amount of time elapsed from another instant to this one, or
71    /// zero duration if that instant is earlier than this one.
72    ///
73    /// # Examples
74    ///
75    /// ```
76    /// use kayrx_timer::{Duration, Instant, delay_for};
77    /// use kayrx_karx;
78    ///
79    /// fn main() {
80    ///          kayrx_karx::exec(async {
81    ///              let now = Instant::now();
82    ///              delay_for(Duration::new(1, 0)).await;
83    ///              let new_now = Instant::now();
84    ///              println!("{:?}", new_now.saturating_duration_since(now));
85    ///              println!("{:?}", now.saturating_duration_since(new_now)); // 0ns
86    ///          });
87    /// }
88    /// ```
89    pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
90        self.std.saturating_duration_since(earlier.std)
91    }
92
93    /// Returns the amount of time elapsed since this instant was created.
94    ///
95    /// # Panics
96    ///
97    /// This function may panic if the current time is earlier than this
98    /// instant, which is something that can happen if an `Instant` is
99    /// produced synthetically.
100    ///
101    /// # Examples
102    ///
103    /// ```
104    /// use kayrx_timer::{Duration, Instant, delay_for};
105    /// use kayrx_karx;
106    ///
107    /// fn main() {
108    ///          kayrx_karx::exec(async {
109    ///              let instant = Instant::now();
110    ///              let three_secs = Duration::from_secs(3);
111    ///              delay_for(three_secs).await;
112    ///              assert!(instant.elapsed() >= three_secs);
113    ///          });
114    /// }
115    /// ```
116    pub fn elapsed(&self) -> Duration {
117        Instant::now() - *self
118    }
119
120    /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be
121    /// represented as `Instant` (which means it's inside the bounds of the
122    /// underlying data structure), `None` otherwise.
123    pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
124        self.std.checked_add(duration).map(Instant::from_std)
125    }
126
127    /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be
128    /// represented as `Instant` (which means it's inside the bounds of the
129    /// underlying data structure), `None` otherwise.
130    pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
131        self.std.checked_sub(duration).map(Instant::from_std)
132    }
133}
134
135impl From<std::time::Instant> for Instant {
136    fn from(time: std::time::Instant) -> Instant {
137        Instant::from_std(time)
138    }
139}
140
141impl From<Instant> for std::time::Instant {
142    fn from(time: Instant) -> std::time::Instant {
143        time.into_std()
144    }
145}
146
147impl ops::Add<Duration> for Instant {
148    type Output = Instant;
149
150    fn add(self, other: Duration) -> Instant {
151        Instant::from_std(self.std + other)
152    }
153}
154
155impl ops::AddAssign<Duration> for Instant {
156    fn add_assign(&mut self, rhs: Duration) {
157        *self = *self + rhs;
158    }
159}
160
161impl ops::Sub for Instant {
162    type Output = Duration;
163
164    fn sub(self, rhs: Instant) -> Duration {
165        self.std - rhs.std
166    }
167}
168
169impl ops::Sub<Duration> for Instant {
170    type Output = Instant;
171
172    fn sub(self, rhs: Duration) -> Instant {
173        Instant::from_std(self.std - rhs)
174    }
175}
176
177impl ops::SubAssign<Duration> for Instant {
178    fn sub_assign(&mut self, rhs: Duration) {
179        *self = *self - rhs;
180    }
181}
182
183impl fmt::Debug for Instant {
184    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
185        self.std.fmt(fmt)
186    }
187}
188
189mod variant {
190    use super::Instant;
191
192    pub(super) fn now() -> Instant {
193        Instant::from_std(std::time::Instant::now())
194    }
195}