Skip to main content

nuclei/time/
instant.rs

1//! [`Instant`]: a point on the runtime's clock, which can be paused and
2//! advanced (see [`pause`](super::pause)); otherwise std's `Instant`.
3
4use core::fmt;
5use core::ops::{Add, AddAssign, Sub, SubAssign};
6use std::time::Duration;
7
8/// A point in time on the clock of the runtime the code runs in.
9///
10/// It is std's [`Instant`](std::time::Instant) as long as the runtime's clock
11/// runs as the system's; [`pause`](super::pause) stops it and
12/// [`advance`](super::advance) moves it, and every timer follows it. The two
13/// convert both ways ([`from_std`](Self::from_std), [`into_std`](Self::into_std)).
14#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct Instant(std::time::Instant);
16
17impl Instant {
18    /// The time now on the runtime's clock.
19    #[inline]
20    pub fn now() -> Self {
21        Self(super::clock::now())
22    }
23
24    /// The instant `std` names.
25    pub fn from_std(std: std::time::Instant) -> Self {
26        Self(std)
27    }
28
29    /// This instant as std's.
30    pub fn into_std(self) -> std::time::Instant {
31        self.0
32    }
33
34    /// The time from `earlier` to this instant, zero if `earlier` is later.
35    pub fn duration_since(&self, earlier: Self) -> Duration {
36        self.0.saturating_duration_since(earlier.0)
37    }
38
39    /// The time from `earlier` to this instant, `None` if `earlier` is later.
40    pub fn checked_duration_since(&self, earlier: Self) -> Option<Duration> {
41        self.0.checked_duration_since(earlier.0)
42    }
43
44    /// The time from `earlier` to this instant, zero if `earlier` is later.
45    pub fn saturating_duration_since(&self, earlier: Self) -> Duration {
46        self.0.saturating_duration_since(earlier.0)
47    }
48
49    /// The time on the runtime's clock since this instant.
50    pub fn elapsed(&self) -> Duration {
51        Self::now().saturating_duration_since(*self)
52    }
53
54    /// This instant moved forward by `duration`, `None` past the clock's range.
55    pub fn checked_add(&self, duration: Duration) -> Option<Self> {
56        self.0.checked_add(duration).map(Self)
57    }
58
59    /// This instant moved back by `duration`, `None` before the clock's range.
60    pub fn checked_sub(&self, duration: Duration) -> Option<Self> {
61        self.0.checked_sub(duration).map(Self)
62    }
63}
64
65impl From<std::time::Instant> for Instant {
66    fn from(std: std::time::Instant) -> Self {
67        Self(std)
68    }
69}
70
71impl From<Instant> for std::time::Instant {
72    fn from(instant: Instant) -> Self {
73        instant.0
74    }
75}
76
77impl Add<Duration> for Instant {
78    type Output = Self;
79
80    /// # Panics
81    ///
82    /// Past the clock's range; [`checked_add`](Instant::checked_add) does not.
83    fn add(self, duration: Duration) -> Self {
84        Self(self.0 + duration)
85    }
86}
87
88impl AddAssign<Duration> for Instant {
89    fn add_assign(&mut self, duration: Duration) {
90        self.0 += duration;
91    }
92}
93
94impl Sub<Duration> for Instant {
95    type Output = Self;
96
97    /// # Panics
98    ///
99    /// Before the clock's range; [`checked_sub`](Instant::checked_sub) does not.
100    fn sub(self, duration: Duration) -> Self {
101        Self(self.0 - duration)
102    }
103}
104
105impl SubAssign<Duration> for Instant {
106    fn sub_assign(&mut self, duration: Duration) {
107        self.0 -= duration;
108    }
109}
110
111impl Sub for Instant {
112    type Output = Duration;
113
114    /// The time from `earlier` to `self`, zero if `earlier` is later.
115    fn sub(self, earlier: Self) -> Duration {
116        self.saturating_duration_since(earlier)
117    }
118}
119
120impl fmt::Debug for Instant {
121    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122        self.0.fmt(f)
123    }
124}