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 #[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 #[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}