Coverage Report

Created: 2025-08-28 06:25

/rust/registry/src/index.crates.io-6f17d22bba15001f/time-0.3.41/src/instant.rs
Line
Count
Source (jump to first uncovered line)
1
//! The [`Instant`] struct and its associated `impl`s.
2
3
#![allow(deprecated)]
4
5
use core::borrow::Borrow;
6
use core::cmp::{Ord, Ordering, PartialEq, PartialOrd};
7
use core::ops::{Add, Sub};
8
use core::time::Duration as StdDuration;
9
use std::time::Instant as StdInstant;
10
11
use crate::internal_macros::{impl_add_assign, impl_sub_assign};
12
use crate::Duration;
13
14
/// A measurement of a monotonically non-decreasing clock. Opaque and useful only with [`Duration`].
15
///
16
/// Instants are always guaranteed to be no less than any previously measured instant when created,
17
/// and are often useful for tasks such as measuring benchmarks or timing how long an operation
18
/// takes.
19
///
20
/// Note, however, that instants are not guaranteed to be **steady**. In other words, each tick of
21
/// the underlying clock may not be the same length (e.g. some seconds may be longer than others).
22
/// An instant may jump forwards or experience time dilation (slow down or speed up), but it will
23
/// never go backwards.
24
///
25
/// Instants are opaque types that can only be compared to one another. There is no method to get
26
/// "the number of seconds" from an instant. Instead, it only allows measuring the duration between
27
/// two instants (or comparing two instants).
28
///
29
/// This implementation allows for operations with signed [`Duration`]s, but is otherwise identical
30
/// to [`std::time::Instant`].
31
#[doc(hidden)]
32
#[deprecated(
33
    since = "0.3.35",
34
    note = "import `std::time::Instant` and `time::ext::InstantExt` instead"
35
)]
36
#[repr(transparent)]
37
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
38
pub struct Instant(pub StdInstant);
39
40
impl Instant {
41
    /// Returns an `Instant` corresponding to "now".
42
    ///
43
    /// ```rust
44
    /// # #![allow(deprecated)]
45
    /// # use time::Instant;
46
    /// println!("{:?}", Instant::now());
47
    /// ```
48
0
    pub fn now() -> Self {
49
0
        Self(StdInstant::now())
50
0
    }
51
52
    /// Returns the amount of time elapsed since this instant was created. The duration will always
53
    /// be nonnegative if the instant is not synthetically created.
54
    ///
55
    /// ```rust
56
    /// # #![allow(deprecated)]
57
    /// # use time::{Instant, ext::{NumericalStdDuration, NumericalDuration}};
58
    /// # use std::thread;
59
    /// let instant = Instant::now();
60
    /// thread::sleep(1.std_milliseconds());
61
    /// assert!(instant.elapsed() >= 1.milliseconds());
62
    /// ```
63
0
    pub fn elapsed(self) -> Duration {
64
0
        Self::now() - self
65
0
    }
66
67
    /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as
68
    /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
69
    /// otherwise.
70
    ///
71
    /// ```rust
72
    /// # #![allow(deprecated)]
73
    /// # use time::{Instant, ext::NumericalDuration};
74
    /// let now = Instant::now();
75
    /// assert_eq!(now.checked_add(5.seconds()), Some(now + 5.seconds()));
76
    /// assert_eq!(now.checked_add((-5).seconds()), Some(now + (-5).seconds()));
77
    /// ```
78
0
    pub fn checked_add(self, duration: Duration) -> Option<Self> {
79
0
        if duration.is_zero() {
80
0
            Some(self)
81
0
        } else if duration.is_positive() {
82
0
            self.0.checked_add(duration.unsigned_abs()).map(Self)
83
        } else {
84
0
            debug_assert!(duration.is_negative());
85
0
            self.0.checked_sub(duration.unsigned_abs()).map(Self)
86
        }
87
0
    }
88
89
    /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
90
    /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
91
    /// otherwise.
92
    ///
93
    /// ```rust
94
    /// # #![allow(deprecated)]
95
    /// # use time::{Instant, ext::NumericalDuration};
96
    /// let now = Instant::now();
97
    /// assert_eq!(now.checked_sub(5.seconds()), Some(now - 5.seconds()));
98
    /// assert_eq!(now.checked_sub((-5).seconds()), Some(now - (-5).seconds()));
99
    /// ```
100
0
    pub fn checked_sub(self, duration: Duration) -> Option<Self> {
101
0
        if duration.is_zero() {
102
0
            Some(self)
103
0
        } else if duration.is_positive() {
104
0
            self.0.checked_sub(duration.unsigned_abs()).map(Self)
105
        } else {
106
0
            debug_assert!(duration.is_negative());
107
0
            self.0.checked_add(duration.unsigned_abs()).map(Self)
108
        }
109
0
    }
110
111
    /// Obtain the inner [`std::time::Instant`].
112
    ///
113
    /// ```rust
114
    /// # #![allow(deprecated)]
115
    /// # use time::Instant;
116
    /// let now = Instant::now();
117
    /// assert_eq!(now.into_inner(), now.0);
118
    /// ```
119
0
    pub const fn into_inner(self) -> StdInstant {
120
0
        self.0
121
0
    }
122
}
123
124
impl From<StdInstant> for Instant {
125
0
    fn from(instant: StdInstant) -> Self {
126
0
        Self(instant)
127
0
    }
128
}
129
130
impl From<Instant> for StdInstant {
131
0
    fn from(instant: Instant) -> Self {
132
0
        instant.0
133
0
    }
134
}
135
136
impl Sub for Instant {
137
    type Output = Duration;
138
139
    /// # Panics
140
    ///
141
    /// This may panic if an overflow occurs.
142
0
    fn sub(self, other: Self) -> Self::Output {
143
0
        match self.0.cmp(&other.0) {
144
0
            Ordering::Equal => Duration::ZERO,
145
0
            Ordering::Greater => (self.0 - other.0)
146
0
                .try_into()
147
0
                .expect("overflow converting `std::time::Duration` to `time::Duration`"),
148
0
            Ordering::Less => -Duration::try_from(other.0 - self.0)
149
0
                .expect("overflow converting `std::time::Duration` to `time::Duration`"),
150
        }
151
0
    }
152
}
153
154
impl Sub<StdInstant> for Instant {
155
    type Output = Duration;
156
157
0
    fn sub(self, other: StdInstant) -> Self::Output {
158
0
        self - Self(other)
159
0
    }
160
}
161
162
impl Sub<Instant> for StdInstant {
163
    type Output = Duration;
164
165
0
    fn sub(self, other: Instant) -> Self::Output {
166
0
        Instant(self) - other
167
0
    }
168
}
169
170
impl Add<Duration> for Instant {
171
    type Output = Self;
172
173
    /// # Panics
174
    ///
175
    /// This function may panic if the resulting point in time cannot be represented by the
176
    /// underlying data structure.
177
0
    fn add(self, duration: Duration) -> Self::Output {
178
0
        if duration.is_positive() {
179
0
            Self(self.0 + duration.unsigned_abs())
180
0
        } else if duration.is_negative() {
181
            #[allow(clippy::unchecked_duration_subtraction)]
182
0
            Self(self.0 - duration.unsigned_abs())
183
        } else {
184
0
            debug_assert!(duration.is_zero());
185
0
            self
186
        }
187
0
    }
188
}
189
190
impl Add<Duration> for StdInstant {
191
    type Output = Self;
192
193
0
    fn add(self, duration: Duration) -> Self::Output {
194
0
        (Instant(self) + duration).0
195
0
    }
196
}
197
198
impl Add<StdDuration> for Instant {
199
    type Output = Self;
200
201
0
    fn add(self, duration: StdDuration) -> Self::Output {
202
0
        Self(self.0 + duration)
203
0
    }
204
}
205
206
impl_add_assign!(Instant: Duration, StdDuration);
207
impl_add_assign!(StdInstant: Duration);
208
209
impl Sub<Duration> for Instant {
210
    type Output = Self;
211
212
    /// # Panics
213
    ///
214
    /// This function may panic if the resulting point in time cannot be represented by the
215
    /// underlying data structure.
216
0
    fn sub(self, duration: Duration) -> Self::Output {
217
0
        if duration.is_positive() {
218
            #[allow(clippy::unchecked_duration_subtraction)]
219
0
            Self(self.0 - duration.unsigned_abs())
220
0
        } else if duration.is_negative() {
221
0
            Self(self.0 + duration.unsigned_abs())
222
        } else {
223
0
            debug_assert!(duration.is_zero());
224
0
            self
225
        }
226
0
    }
227
}
228
229
impl Sub<Duration> for StdInstant {
230
    type Output = Self;
231
232
0
    fn sub(self, duration: Duration) -> Self::Output {
233
0
        (Instant(self) - duration).0
234
0
    }
235
}
236
237
impl Sub<StdDuration> for Instant {
238
    type Output = Self;
239
240
    /// # Panics
241
    ///
242
    /// This function may panic if the resulting point in time cannot be represented by the
243
    /// underlying data structure.
244
0
    fn sub(self, duration: StdDuration) -> Self::Output {
245
0
        #[allow(clippy::unchecked_duration_subtraction)]
246
0
        Self(self.0 - duration)
247
0
    }
248
}
249
250
impl_sub_assign!(Instant: Duration, StdDuration);
251
impl_sub_assign!(StdInstant: Duration);
252
253
impl PartialEq<StdInstant> for Instant {
254
0
    fn eq(&self, rhs: &StdInstant) -> bool {
255
0
        self.0.eq(rhs)
256
0
    }
257
}
258
259
impl PartialEq<Instant> for StdInstant {
260
0
    fn eq(&self, rhs: &Instant) -> bool {
261
0
        self.eq(&rhs.0)
262
0
    }
263
}
264
265
impl PartialOrd<StdInstant> for Instant {
266
0
    fn partial_cmp(&self, rhs: &StdInstant) -> Option<Ordering> {
267
0
        self.0.partial_cmp(rhs)
268
0
    }
269
}
270
271
impl PartialOrd<Instant> for StdInstant {
272
0
    fn partial_cmp(&self, rhs: &Instant) -> Option<Ordering> {
273
0
        self.partial_cmp(&rhs.0)
274
0
    }
275
}
276
277
impl AsRef<StdInstant> for Instant {
278
0
    fn as_ref(&self) -> &StdInstant {
279
0
        &self.0
280
0
    }
281
}
282
283
impl Borrow<StdInstant> for Instant {
284
0
    fn borrow(&self) -> &StdInstant {
285
0
        &self.0
286
0
    }
287
}