Skip to main content

nu_utils/
time.rs

1#![allow(
2    clippy::disallowed_types,
3    reason = "only allow std::time::Instant here when it's not WASM"
4)]
5#![allow(clippy::unchecked_time_subtraction, reason = "just forwarded")]
6
7use std::{
8    ops::{Add, AddAssign, Deref, Sub, SubAssign},
9    time::Duration,
10};
11
12#[cfg(not(target_arch = "wasm32"))]
13use std::time::Instant as InnerInstant;
14
15#[cfg(target_arch = "wasm32")]
16pub use web_time::Instant as InnerInstant;
17
18/// WASM-safe alternative to [`std::time::Instant`].
19///
20/// This is a thin wrapper around either `std::time::Instant` or `web_time::Instant` to allow
21/// compiling for WASM without issues.
22/// `web_time::Instant` usually re-exports `std::time::Instant` on non-WASM targets but this does
23/// not allow usage of `clippy::disallowed-types` properly.
24/// This wrapper fixes that.
25///
26/// For any reference, see [`std::time::Instant`].
27#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
28pub struct Instant(InnerInstant);
29
30impl Instant {
31    /// Returns an instant corresponding to "now".
32    ///
33    /// See [`Instant::now`](InnerInstant::now).
34    pub fn now() -> Self {
35        Instant(InnerInstant::now())
36    }
37
38    /// Returns the amount of time elapsed from another instant to this one, or zero duration if
39    /// that instant is later than this one.
40    ///
41    /// See [`Instant::duration_since`](InnerInstant::duration_since).
42    pub fn duration_since(&self, earlier: Instant) -> Duration {
43        self.0.duration_since(earlier.0)
44    }
45
46    /// Returns the amount of time elapsed from another instant to this one, or None if that instant
47    /// is later than this one.
48    ///
49    /// See [`Instant::checked_duration_since`](InnerInstant::checked_duration_since).
50    pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
51        self.0.checked_duration_since(earlier.0)
52    }
53
54    /// Returns the amount of time elapsed from another instant to this one, or zero duration if
55    /// that instant is later than this one.
56    ///
57    /// See [`Instant::saturating_duration_since`](InnerInstant::saturating_duration_since).
58    pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
59        self.0.saturating_duration_since(earlier.0)
60    }
61
62    /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as
63    /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
64    /// otherwise.
65    ///
66    /// See [`Instant::checked_add`](InnerInstant::checked_add).
67    pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
68        self.0.checked_add(duration).map(Self)
69    }
70
71    /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
72    /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
73    /// otherwise.
74    ///
75    /// See [`Instant::checked_sub`](InnerInstant::checked_sub).
76    pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
77        self.0.checked_sub(duration).map(Self)
78    }
79}
80
81impl Deref for Instant {
82    type Target = InnerInstant;
83
84    fn deref(&self) -> &Self::Target {
85        &self.0
86    }
87}
88
89impl Add<Duration> for Instant {
90    type Output = Instant;
91
92    fn add(self, rhs: Duration) -> Self::Output {
93        Instant(self.0.add(rhs))
94    }
95}
96
97impl AddAssign<Duration> for Instant {
98    fn add_assign(&mut self, rhs: Duration) {
99        self.0.add_assign(rhs)
100    }
101}
102
103impl Sub<Duration> for Instant {
104    type Output = Instant;
105
106    fn sub(self, rhs: Duration) -> Self::Output {
107        Instant(self.0.sub(rhs))
108    }
109}
110
111impl SubAssign<Duration> for Instant {
112    fn sub_assign(&mut self, rhs: Duration) {
113        self.0.sub_assign(rhs)
114    }
115}
116
117impl Sub<Instant> for Instant {
118    type Output = Duration;
119
120    fn sub(self, rhs: Instant) -> Self::Output {
121        self.0.sub(rhs.0)
122    }
123}
124
125impl From<InnerInstant> for Instant {
126    fn from(value: InnerInstant) -> Self {
127        Self(value)
128    }
129}