Coverage Report

Created: 2026-02-26 07:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/time-0.3.47/src/instant.rs
Line
Count
Source
1
//! The [`Instant`] struct and its associated `impl`s.
2
3
#![expect(deprecated)]
4
5
use core::borrow::Borrow;
6
use core::cmp::{Ord, Ordering, PartialEq, PartialOrd};
7
use core::ops::{Add, AddAssign, Sub, SubAssign};
8
use core::time::Duration as StdDuration;
9
use std::time::Instant as StdInstant;
10
11
use crate::Duration;
12
13
/// A measurement of a monotonically non-decreasing clock. Opaque and useful only with [`Duration`].
14
///
15
/// Instants are always guaranteed to be no less than any previously measured instant when created,
16
/// and are often useful for tasks such as measuring benchmarks or timing how long an operation
17
/// takes.
18
///
19
/// Note, however, that instants are not guaranteed to be **steady**. In other words, each tick of
20
/// the underlying clock may not be the same length (e.g. some seconds may be longer than others).
21
/// An instant may jump forwards or experience time dilation (slow down or speed up), but it will
22
/// never go backwards.
23
///
24
/// Instants are opaque types that can only be compared to one another. There is no method to get
25
/// "the number of seconds" from an instant. Instead, it only allows measuring the duration between
26
/// two instants (or comparing two instants).
27
///
28
/// This implementation allows for operations with signed [`Duration`]s, but is otherwise identical
29
/// to [`std::time::Instant`].
30
#[doc(hidden)]
31
#[deprecated(
32
    since = "0.3.35",
33
    note = "import `std::time::Instant` and `time::ext::InstantExt` instead"
34
)]
35
#[repr(transparent)]
36
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
37
pub struct Instant(pub StdInstant);
38
39
impl Instant {
40
    /// Returns an `Instant` corresponding to "now".
41
    ///
42
    /// ```rust
43
    /// # #![expect(deprecated)]
44
    /// # use time::Instant;
45
    /// println!("{:?}", Instant::now());
46
    /// ```
47
    #[inline]
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
    /// # #![expect(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
    #[inline]
64
0
    pub fn elapsed(self) -> Duration {
65
0
        Self::now() - self
66
0
    }
67
68
    /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as
69
    /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
70
    /// otherwise.
71
    ///
72
    /// ```rust
73
    /// # #![expect(deprecated)]
74
    /// # use time::{Instant, ext::NumericalDuration};
75
    /// let now = Instant::now();
76
    /// assert_eq!(now.checked_add(5.seconds()), Some(now + 5.seconds()));
77
    /// assert_eq!(now.checked_add((-5).seconds()), Some(now + (-5).seconds()));
78
    /// ```
79
    #[inline]
80
0
    pub fn checked_add(self, duration: Duration) -> Option<Self> {
81
0
        if duration.is_zero() {
82
0
            Some(self)
83
0
        } else if duration.is_positive() {
84
0
            self.0.checked_add(duration.unsigned_abs()).map(Self)
85
        } else {
86
0
            debug_assert!(duration.is_negative());
87
0
            self.0.checked_sub(duration.unsigned_abs()).map(Self)
88
        }
89
0
    }
90
91
    /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
92
    /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
93
    /// otherwise.
94
    ///
95
    /// ```rust
96
    /// # #![expect(deprecated)]
97
    /// # use time::{Instant, ext::NumericalDuration};
98
    /// let now = Instant::now();
99
    /// assert_eq!(now.checked_sub(5.seconds()), Some(now - 5.seconds()));
100
    /// assert_eq!(now.checked_sub((-5).seconds()), Some(now - (-5).seconds()));
101
    /// ```
102
    #[inline]
103
0
    pub fn checked_sub(self, duration: Duration) -> Option<Self> {
104
0
        if duration.is_zero() {
105
0
            Some(self)
106
0
        } else if duration.is_positive() {
107
0
            self.0.checked_sub(duration.unsigned_abs()).map(Self)
108
        } else {
109
0
            debug_assert!(duration.is_negative());
110
0
            self.0.checked_add(duration.unsigned_abs()).map(Self)
111
        }
112
0
    }
113
114
    /// Obtain the inner [`std::time::Instant`].
115
    ///
116
    /// ```rust
117
    /// # #![expect(deprecated)]
118
    /// # use time::Instant;
119
    /// let now = Instant::now();
120
    /// assert_eq!(now.into_inner(), now.0);
121
    /// ```
122
    #[inline]
123
0
    pub const fn into_inner(self) -> StdInstant {
124
0
        self.0
125
0
    }
126
}
127
128
impl From<StdInstant> for Instant {
129
    #[inline]
130
0
    fn from(instant: StdInstant) -> Self {
131
0
        Self(instant)
132
0
    }
133
}
134
135
impl From<Instant> for StdInstant {
136
    #[inline]
137
0
    fn from(instant: Instant) -> Self {
138
0
        instant.0
139
0
    }
140
}
141
142
impl Sub for Instant {
143
    type Output = Duration;
144
145
    /// # Panics
146
    ///
147
    /// This may panic if an overflow occurs.
148
    #[inline]
149
0
    fn sub(self, other: Self) -> Self::Output {
150
0
        match self.0.cmp(&other.0) {
151
0
            Ordering::Equal => Duration::ZERO,
152
0
            Ordering::Greater => (self.0 - other.0)
153
0
                .try_into()
154
0
                .expect("overflow converting `std::time::Duration` to `time::Duration`"),
155
0
            Ordering::Less => -Duration::try_from(other.0 - self.0)
156
0
                .expect("overflow converting `std::time::Duration` to `time::Duration`"),
157
        }
158
0
    }
159
}
160
161
impl Sub<StdInstant> for Instant {
162
    type Output = Duration;
163
164
    #[inline]
165
0
    fn sub(self, other: StdInstant) -> Self::Output {
166
0
        self - Self(other)
167
0
    }
168
}
169
170
impl Sub<Instant> for StdInstant {
171
    type Output = Duration;
172
173
    #[inline]
174
0
    fn sub(self, other: Instant) -> Self::Output {
175
0
        Instant(self) - other
176
0
    }
177
}
178
179
impl Add<Duration> for Instant {
180
    type Output = Self;
181
182
    /// # Panics
183
    ///
184
    /// This function may panic if the resulting point in time cannot be represented by the
185
    /// underlying data structure.
186
    #[inline]
187
0
    fn add(self, duration: Duration) -> Self::Output {
188
0
        if duration.is_positive() {
189
0
            Self(self.0 + duration.unsigned_abs())
190
0
        } else if duration.is_negative() {
191
            #[expect(clippy::unchecked_time_subtraction)]
192
0
            Self(self.0 - duration.unsigned_abs())
193
        } else {
194
0
            debug_assert!(duration.is_zero());
195
0
            self
196
        }
197
0
    }
198
}
199
200
impl Add<Duration> for StdInstant {
201
    type Output = Self;
202
203
    /// # Panics
204
    ///
205
    /// This function may panic if the resulting point in time cannot be represented by the
206
    /// underlying data structure.
207
    #[inline]
208
0
    fn add(self, duration: Duration) -> Self::Output {
209
0
        (Instant(self) + duration).0
210
0
    }
211
}
212
213
impl Add<StdDuration> for Instant {
214
    type Output = Self;
215
216
    /// # Panics
217
    ///
218
    /// This function may panic if the resulting point in time cannot be represented by the
219
    /// underlying data structure.
220
    #[inline]
221
0
    fn add(self, duration: StdDuration) -> Self::Output {
222
0
        Self(self.0 + duration)
223
0
    }
224
}
225
226
impl AddAssign<Duration> for Instant {
227
    /// # Panics
228
    ///
229
    /// This function may panic if the resulting point in time cannot be represented by the
230
    /// underlying data structure.
231
    #[inline]
232
0
    fn add_assign(&mut self, rhs: Duration) {
233
0
        *self = *self + rhs;
234
0
    }
235
}
236
237
impl AddAssign<StdDuration> for Instant {
238
    /// # Panics
239
    ///
240
    /// This function may panic if the resulting point in time cannot be represented by the
241
    /// underlying data structure.
242
    #[inline]
243
0
    fn add_assign(&mut self, rhs: StdDuration) {
244
0
        *self = *self + rhs;
245
0
    }
246
}
247
248
impl AddAssign<Duration> for StdInstant {
249
    /// # Panics
250
    ///
251
    /// This function may panic if the resulting point in time cannot be represented by the
252
    /// underlying data structure.
253
    #[inline]
254
0
    fn add_assign(&mut self, rhs: Duration) {
255
0
        *self = *self + rhs;
256
0
    }
257
}
258
259
impl Sub<Duration> for Instant {
260
    type Output = Self;
261
262
    /// # Panics
263
    ///
264
    /// This function may panic if the resulting point in time cannot be represented by the
265
    /// underlying data structure.
266
    #[inline]
267
0
    fn sub(self, duration: Duration) -> Self::Output {
268
0
        if duration.is_positive() {
269
            #[expect(clippy::unchecked_time_subtraction)]
270
0
            Self(self.0 - duration.unsigned_abs())
271
0
        } else if duration.is_negative() {
272
0
            Self(self.0 + duration.unsigned_abs())
273
        } else {
274
0
            debug_assert!(duration.is_zero());
275
0
            self
276
        }
277
0
    }
278
}
279
280
impl Sub<Duration> for StdInstant {
281
    type Output = Self;
282
283
    /// # Panics
284
    ///
285
    /// This function may panic if the resulting point in time cannot be represented by the
286
    /// underlying data structure.
287
    #[inline]
288
0
    fn sub(self, duration: Duration) -> Self::Output {
289
0
        (Instant(self) - duration).0
290
0
    }
291
}
292
293
impl Sub<StdDuration> for Instant {
294
    type Output = Self;
295
296
    /// # Panics
297
    ///
298
    /// This function may panic if the resulting point in time cannot be represented by the
299
    /// underlying data structure.
300
    #[inline]
301
0
    fn sub(self, duration: StdDuration) -> Self::Output {
302
        #[expect(clippy::unchecked_time_subtraction)]
303
0
        Self(self.0 - duration)
304
0
    }
305
}
306
307
impl SubAssign<Duration> for Instant {
308
    /// # Panics
309
    ///
310
    /// This function may panic if the resulting point in time cannot be represented by the
311
    /// underlying data structure.
312
    #[inline]
313
0
    fn sub_assign(&mut self, rhs: Duration) {
314
0
        *self = *self - rhs;
315
0
    }
316
}
317
318
impl SubAssign<StdDuration> for Instant {
319
    /// # Panics
320
    ///
321
    /// This function may panic if the resulting point in time cannot be represented by the
322
    /// underlying data structure.
323
    #[inline]
324
0
    fn sub_assign(&mut self, rhs: StdDuration) {
325
0
        *self = *self - rhs;
326
0
    }
327
}
328
329
impl SubAssign<Duration> for StdInstant {
330
    /// # Panics
331
    ///
332
    /// This function may panic if the resulting point in time cannot be represented by the
333
    /// underlying data structure.
334
    #[inline]
335
0
    fn sub_assign(&mut self, rhs: Duration) {
336
0
        *self = *self - rhs;
337
0
    }
338
}
339
340
impl PartialEq<StdInstant> for Instant {
341
    #[inline]
342
0
    fn eq(&self, rhs: &StdInstant) -> bool {
343
0
        self.0.eq(rhs)
344
0
    }
345
}
346
347
impl PartialEq<Instant> for StdInstant {
348
    #[inline]
349
0
    fn eq(&self, rhs: &Instant) -> bool {
350
0
        self.eq(&rhs.0)
351
0
    }
352
}
353
354
impl PartialOrd<StdInstant> for Instant {
355
    #[inline]
356
0
    fn partial_cmp(&self, rhs: &StdInstant) -> Option<Ordering> {
357
0
        self.0.partial_cmp(rhs)
358
0
    }
359
}
360
361
impl PartialOrd<Instant> for StdInstant {
362
    #[inline]
363
0
    fn partial_cmp(&self, rhs: &Instant) -> Option<Ordering> {
364
0
        self.partial_cmp(&rhs.0)
365
0
    }
366
}
367
368
impl AsRef<StdInstant> for Instant {
369
    #[inline]
370
0
    fn as_ref(&self) -> &StdInstant {
371
0
        &self.0
372
0
    }
373
}
374
375
impl Borrow<StdInstant> for Instant {
376
    #[inline]
377
0
    fn borrow(&self) -> &StdInstant {
378
0
        &self.0
379
0
    }
380
}