Skip to main content

argui_animation/
time.rs

1use std::ops::{Add, AddAssign, Sub};
2
3/// A non-negative span represented exactly in nanoseconds.
4#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
5pub struct Duration(u64);
6
7impl Duration {
8    pub const ZERO: Self = Self(0);
9
10    #[must_use]
11    pub const fn from_nanos(nanos: u64) -> Self {
12        Self(nanos)
13    }
14
15    #[must_use]
16    pub const fn from_micros(micros: u64) -> Self {
17        Self(micros.saturating_mul(1_000))
18    }
19
20    #[must_use]
21    pub const fn from_millis(millis: u64) -> Self {
22        Self(millis.saturating_mul(1_000_000))
23    }
24
25    #[must_use]
26    pub const fn from_secs(seconds: u64) -> Self {
27        Self(seconds.saturating_mul(1_000_000_000))
28    }
29
30    #[must_use]
31    pub const fn as_nanos(self) -> u64 {
32        self.0
33    }
34
35    #[must_use]
36    pub fn as_secs_f64(self) -> f64 {
37        self.0 as f64 / 1_000_000_000.0
38    }
39}
40
41impl Add for Duration {
42    type Output = Self;
43
44    fn add(self, rhs: Self) -> Self::Output {
45        Self(self.0.saturating_add(rhs.0))
46    }
47}
48
49impl AddAssign for Duration {
50    fn add_assign(&mut self, rhs: Self) {
51        *self = *self + rhs;
52    }
53}
54
55impl Sub for Duration {
56    type Output = Self;
57
58    fn sub(self, rhs: Self) -> Self::Output {
59        Self(self.0.saturating_sub(rhs.0))
60    }
61}
62
63impl From<std::time::Duration> for Duration {
64    fn from(value: std::time::Duration) -> Self {
65        Self(u64::try_from(value.as_nanos()).unwrap_or(u64::MAX))
66    }
67}
68
69impl From<Duration> for std::time::Duration {
70    fn from(value: Duration) -> Self {
71        Self::from_nanos(value.0)
72    }
73}
74
75/// A monotonic timestamp relative to a clock-defined origin.
76#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
77pub struct Time(u64);
78
79impl Time {
80    pub const ZERO: Self = Self(0);
81
82    #[must_use]
83    pub const fn from_nanos(nanos: u64) -> Self {
84        Self(nanos)
85    }
86
87    #[must_use]
88    pub const fn as_nanos(self) -> u64 {
89        self.0
90    }
91
92    #[must_use]
93    pub const fn duration_since(self, earlier: Self) -> Duration {
94        Duration::from_nanos(self.0.saturating_sub(earlier.0))
95    }
96}
97
98impl Add<Duration> for Time {
99    type Output = Self;
100
101    fn add(self, rhs: Duration) -> Self::Output {
102        Self(self.0.saturating_add(rhs.as_nanos()))
103    }
104}
105
106impl Sub<Time> for Time {
107    type Output = Duration;
108
109    fn sub(self, rhs: Time) -> Self::Output {
110        self.duration_since(rhs)
111    }
112}