Skip to main content

bma_ts/
monotonic.rs

1#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
2pub struct Monotonic(pub(crate) Duration);
3
4use std::time::Duration;
5#[cfg(target_family = "windows")]
6use std::time::Instant;
7#[cfg(target_family = "wasm")]
8use web_time::Instant;
9
10#[cfg(not(target_family = "unix"))]
11static STARTED_AT: std::sync::LazyLock<Instant> = std::sync::LazyLock::new(|| Instant::now());
12
13impl Monotonic {
14    /// On non-UNIX platforms returns time since the first access
15    ///
16    /// # Panics
17    ///
18    /// On UNIX platforms will panic if the system monotonic clock is not available
19    #[inline]
20    #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
21    #[cfg(target_family = "unix")]
22    pub fn now() -> Self {
23        let t = nix::time::clock_gettime(nix::time::ClockId::CLOCK_MONOTONIC).unwrap();
24        Self(Duration::new(t.tv_sec() as u64, t.tv_nsec() as u32))
25    }
26    /// # Panics
27    ///
28    /// On UNIX platforms will panic if the system monotonic clock is not available
29    #[inline]
30    #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
31    #[cfg(target_family = "unix")]
32    pub fn now_rounded() -> Self {
33        let t = nix::time::clock_gettime(nix::time::ClockId::CLOCK_MONOTONIC).unwrap();
34        Self(Duration::new(t.tv_sec() as u64, 0))
35    }
36    #[cfg(not(target_family = "unix"))]
37    #[inline]
38    pub fn now() -> Self {
39        STARTED_AT.elapsed().into()
40    }
41    #[cfg(not(target_family = "unix"))]
42    #[inline]
43    pub fn now_rounded() -> Self {
44        Monotonic::from_secs(STARTED_AT.elapsed().as_secs())
45    }
46    #[inline]
47    pub fn elapsed(&self) -> Duration {
48        Self::now().0 - self.0
49    }
50    #[inline]
51    pub fn duration_since(&self, earlier: Self) -> Duration {
52        self.0 - earlier.0
53    }
54}