Coverage Report

Created: 2026-02-14 06:42

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