1 | #![allow (clippy::trivially_copy_pass_by_ref)] |
2 | |
3 | use std::fmt; |
4 | use std::ops; |
5 | use std::time::Duration; |
6 | |
7 | /// A measurement of a monotonically nondecreasing clock. |
8 | /// Opaque and useful only with `Duration`. |
9 | /// |
10 | /// Instants are always guaranteed to be no less than any previously measured |
11 | /// instant when created, and are often useful for tasks such as measuring |
12 | /// benchmarks or timing how long an operation takes. |
13 | /// |
14 | /// Note, however, that instants are not guaranteed to be **steady**. In other |
15 | /// words, each tick of the underlying clock may not be the same length (e.g. |
16 | /// some seconds may be longer than others). An instant may jump forwards or |
17 | /// experience time dilation (slow down or speed up), but it will never go |
18 | /// backwards. |
19 | /// |
20 | /// Instants are opaque types that can only be compared to one another. There is |
21 | /// no method to get "the number of seconds" from an instant. Instead, it only |
22 | /// allows measuring the duration between two instants (or comparing two |
23 | /// instants). |
24 | /// |
25 | /// The size of an `Instant` struct may vary depending on the target operating |
26 | /// system. |
27 | /// |
28 | /// # Note |
29 | /// |
30 | /// This type wraps the inner `std` variant and is used to align the Tokio |
31 | /// clock for uses of `now()`. This can be useful for testing where you can |
32 | /// take advantage of `time::pause()` and `time::advance()`. |
33 | #[derive (Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)] |
34 | pub struct Instant { |
35 | std: std::time::Instant, |
36 | } |
37 | |
38 | impl Instant { |
39 | /// Returns an instant corresponding to "now". |
40 | /// |
41 | /// # Examples |
42 | /// |
43 | /// ``` |
44 | /// use tokio::time::Instant; |
45 | /// |
46 | /// let now = Instant::now(); |
47 | /// ``` |
48 | pub fn now() -> Instant { |
49 | variant::now() |
50 | } |
51 | |
52 | /// Create a `tokio::time::Instant` from a `std::time::Instant`. |
53 | pub fn from_std(std: std::time::Instant) -> Instant { |
54 | Instant { std } |
55 | } |
56 | |
57 | pub(crate) fn far_future() -> Instant { |
58 | // Roughly 30 years from now. |
59 | // API does not provide a way to obtain max `Instant` |
60 | // or convert specific date in the future to instant. |
61 | // 1000 years overflows on macOS, 100 years overflows on FreeBSD. |
62 | Self::now() + Duration::from_secs(86400 * 365 * 30) |
63 | } |
64 | |
65 | /// Convert the value into a `std::time::Instant`. |
66 | pub fn into_std(self) -> std::time::Instant { |
67 | self.std |
68 | } |
69 | |
70 | /// Returns the amount of time elapsed from another instant to this one, or |
71 | /// zero duration if that instant is later than this one. |
72 | pub fn duration_since(&self, earlier: Instant) -> Duration { |
73 | self.std.saturating_duration_since(earlier.std) |
74 | } |
75 | |
76 | /// Returns the amount of time elapsed from another instant to this one, or |
77 | /// None if that instant is later than this one. |
78 | /// |
79 | /// # Examples |
80 | /// |
81 | /// ``` |
82 | /// use tokio::time::{Duration, Instant, sleep}; |
83 | /// |
84 | /// #[tokio::main] |
85 | /// async fn main() { |
86 | /// let now = Instant::now(); |
87 | /// sleep(Duration::new(1, 0)).await; |
88 | /// let new_now = Instant::now(); |
89 | /// println!("{:?}" , new_now.checked_duration_since(now)); |
90 | /// println!("{:?}" , now.checked_duration_since(new_now)); // None |
91 | /// } |
92 | /// ``` |
93 | pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> { |
94 | self.std.checked_duration_since(earlier.std) |
95 | } |
96 | |
97 | /// Returns the amount of time elapsed from another instant to this one, or |
98 | /// zero duration if that instant is later than this one. |
99 | /// |
100 | /// # Examples |
101 | /// |
102 | /// ``` |
103 | /// use tokio::time::{Duration, Instant, sleep}; |
104 | /// |
105 | /// #[tokio::main] |
106 | /// async fn main() { |
107 | /// let now = Instant::now(); |
108 | /// sleep(Duration::new(1, 0)).await; |
109 | /// let new_now = Instant::now(); |
110 | /// println!("{:?}" , new_now.saturating_duration_since(now)); |
111 | /// println!("{:?}" , now.saturating_duration_since(new_now)); // 0ns |
112 | /// } |
113 | /// ``` |
114 | pub fn saturating_duration_since(&self, earlier: Instant) -> Duration { |
115 | self.std.saturating_duration_since(earlier.std) |
116 | } |
117 | |
118 | /// Returns the amount of time elapsed since this instant was created, |
119 | /// or zero duration if that this instant is in the future. |
120 | /// |
121 | /// # Examples |
122 | /// |
123 | /// ``` |
124 | /// use tokio::time::{Duration, Instant, sleep}; |
125 | /// |
126 | /// #[tokio::main] |
127 | /// async fn main() { |
128 | /// let instant = Instant::now(); |
129 | /// let three_secs = Duration::from_secs(3); |
130 | /// sleep(three_secs).await; |
131 | /// assert!(instant.elapsed() >= three_secs); |
132 | /// } |
133 | /// ``` |
134 | pub fn elapsed(&self) -> Duration { |
135 | Instant::now().saturating_duration_since(*self) |
136 | } |
137 | |
138 | /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be |
139 | /// represented as `Instant` (which means it's inside the bounds of the |
140 | /// underlying data structure), `None` otherwise. |
141 | pub fn checked_add(&self, duration: Duration) -> Option<Instant> { |
142 | self.std.checked_add(duration).map(Instant::from_std) |
143 | } |
144 | |
145 | /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be |
146 | /// represented as `Instant` (which means it's inside the bounds of the |
147 | /// underlying data structure), `None` otherwise. |
148 | pub fn checked_sub(&self, duration: Duration) -> Option<Instant> { |
149 | self.std.checked_sub(duration).map(Instant::from_std) |
150 | } |
151 | } |
152 | |
153 | impl From<std::time::Instant> for Instant { |
154 | fn from(time: std::time::Instant) -> Instant { |
155 | Instant::from_std(time) |
156 | } |
157 | } |
158 | |
159 | impl From<Instant> for std::time::Instant { |
160 | fn from(time: Instant) -> std::time::Instant { |
161 | time.into_std() |
162 | } |
163 | } |
164 | |
165 | impl ops::Add<Duration> for Instant { |
166 | type Output = Instant; |
167 | |
168 | fn add(self, other: Duration) -> Instant { |
169 | Instant::from_std(self.std + other) |
170 | } |
171 | } |
172 | |
173 | impl ops::AddAssign<Duration> for Instant { |
174 | fn add_assign(&mut self, rhs: Duration) { |
175 | *self = *self + rhs; |
176 | } |
177 | } |
178 | |
179 | impl ops::Sub for Instant { |
180 | type Output = Duration; |
181 | |
182 | fn sub(self, rhs: Instant) -> Duration { |
183 | self.std.saturating_duration_since(earlier:rhs.std) |
184 | } |
185 | } |
186 | |
187 | impl ops::Sub<Duration> for Instant { |
188 | type Output = Instant; |
189 | |
190 | fn sub(self, rhs: Duration) -> Instant { |
191 | Instant::from_std(std::time::Instant::sub(self.std, rhs)) |
192 | } |
193 | } |
194 | |
195 | impl ops::SubAssign<Duration> for Instant { |
196 | fn sub_assign(&mut self, rhs: Duration) { |
197 | *self = *self - rhs; |
198 | } |
199 | } |
200 | |
201 | impl fmt::Debug for Instant { |
202 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
203 | self.std.fmt(fmt) |
204 | } |
205 | } |
206 | |
207 | #[cfg (not(feature = "test-util" ))] |
208 | mod variant { |
209 | use super::Instant; |
210 | |
211 | pub(super) fn now() -> Instant { |
212 | Instant::from_std(std::time::Instant::now()) |
213 | } |
214 | } |
215 | |
216 | #[cfg (feature = "test-util" )] |
217 | mod variant { |
218 | use super::Instant; |
219 | |
220 | pub(super) fn now() -> Instant { |
221 | crate::time::clock::now() |
222 | } |
223 | } |
224 | |