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}