broker_tokio/time/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 tokio::time::Instant;
21 ///
22 /// let now = Instant::now();
23 /// ```
24 pub fn now() -> Instant {
25 variant::now()
26 }
27
28 /// Create a `tokio::time::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 tokio::time::{Duration, Instant, delay_for};
54 ///
55 /// #[tokio::main]
56 /// async fn main() {
57 /// let now = Instant::now();
58 /// delay_for(Duration::new(1, 0)).await;
59 /// let new_now = Instant::now();
60 /// println!("{:?}", new_now.checked_duration_since(now));
61 /// println!("{:?}", now.checked_duration_since(new_now)); // None
62 /// }
63 /// ```
64 pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
65 self.std.checked_duration_since(earlier.std)
66 }
67
68 /// Returns the amount of time elapsed from another instant to this one, or
69 /// zero duration if that instant is earlier than this one.
70 ///
71 /// # Examples
72 ///
73 /// ```
74 /// use tokio::time::{Duration, Instant, delay_for};
75 ///
76 /// #[tokio::main]
77 /// async fn main() {
78 /// let now = Instant::now();
79 /// delay_for(Duration::new(1, 0)).await;
80 /// let new_now = Instant::now();
81 /// println!("{:?}", new_now.saturating_duration_since(now));
82 /// println!("{:?}", now.saturating_duration_since(new_now)); // 0ns
83 /// }
84 /// ```
85 pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
86 self.std.saturating_duration_since(earlier.std)
87 }
88
89 /// Returns the amount of time elapsed since this instant was created.
90 ///
91 /// # Panics
92 ///
93 /// This function may panic if the current time is earlier than this
94 /// instant, which is something that can happen if an `Instant` is
95 /// produced synthetically.
96 ///
97 /// # Examples
98 ///
99 /// ```
100 /// use tokio::time::{Duration, Instant, delay_for};
101 ///
102 /// #[tokio::main]
103 /// async fn main() {
104 /// let instant = Instant::now();
105 /// let three_secs = Duration::from_secs(3);
106 /// delay_for(three_secs).await;
107 /// assert!(instant.elapsed() >= three_secs);
108 /// }
109 /// ```
110 pub fn elapsed(&self) -> Duration {
111 Instant::now() - *self
112 }
113
114 /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be
115 /// represented as `Instant` (which means it's inside the bounds of the
116 /// underlying data structure), `None` otherwise.
117 pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
118 self.std.checked_add(duration).map(Instant::from_std)
119 }
120
121 /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be
122 /// represented as `Instant` (which means it's inside the bounds of the
123 /// underlying data structure), `None` otherwise.
124 pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
125 self.std.checked_sub(duration).map(Instant::from_std)
126 }
127}
128
129impl From<std::time::Instant> for Instant {
130 fn from(time: std::time::Instant) -> Instant {
131 Instant::from_std(time)
132 }
133}
134
135impl From<Instant> for std::time::Instant {
136 fn from(time: Instant) -> std::time::Instant {
137 time.into_std()
138 }
139}
140
141impl ops::Add<Duration> for Instant {
142 type Output = Instant;
143
144 fn add(self, other: Duration) -> Instant {
145 Instant::from_std(self.std + other)
146 }
147}
148
149impl ops::AddAssign<Duration> for Instant {
150 fn add_assign(&mut self, rhs: Duration) {
151 *self = *self + rhs;
152 }
153}
154
155impl ops::Sub for Instant {
156 type Output = Duration;
157
158 fn sub(self, rhs: Instant) -> Duration {
159 self.std - rhs.std
160 }
161}
162
163impl ops::Sub<Duration> for Instant {
164 type Output = Instant;
165
166 fn sub(self, rhs: Duration) -> Instant {
167 Instant::from_std(self.std - rhs)
168 }
169}
170
171impl ops::SubAssign<Duration> for Instant {
172 fn sub_assign(&mut self, rhs: Duration) {
173 *self = *self - rhs;
174 }
175}
176
177impl fmt::Debug for Instant {
178 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
179 self.std.fmt(fmt)
180 }
181}
182
183#[cfg(not(feature = "test-util"))]
184mod variant {
185 use super::Instant;
186
187 pub(super) fn now() -> Instant {
188 Instant::from_std(std::time::Instant::now())
189 }
190}
191
192#[cfg(feature = "test-util")]
193mod variant {
194 use super::Instant;
195
196 pub(super) fn now() -> Instant {
197 crate::time::clock::now()
198 }
199}