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}