dot15d4/
time.rs

1//! Time structures.
2//!
3//! - [`Instant`] is used to represent a point in time.
4//! - [`Duration`] is used to represent a duration of time.
5
6#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord)]
7#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
8pub struct Instant {
9    us: i64,
10}
11
12impl Instant {
13    /// Create a new `Instant` from microseconds since the epoch.
14    pub const fn from_us(us: i64) -> Self {
15        Self { us }
16    }
17
18    /// Returns the point in time as microseconds since the epoch.
19    pub const fn as_us(&self) -> i64 {
20        self.us
21    }
22}
23
24#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord)]
25#[cfg_attr(feature = "fuzz", derive(arbitrary::Arbitrary))]
26pub struct Duration(i64);
27
28impl Duration {
29    /// Create a new `Duration` from microseconds.
30    pub const fn from_us(us: i64) -> Self {
31        Self(us)
32    }
33
34    /// Returns the duration as microseconds.
35    pub const fn as_us(&self) -> i64 {
36        self.0
37    }
38}
39
40impl core::ops::Sub for Instant {
41    type Output = Self;
42
43    fn sub(self, rhs: Instant) -> Self::Output {
44        Self::from_us(self.as_us() - rhs.as_us())
45    }
46}
47
48impl core::ops::Sub<Duration> for Instant {
49    type Output = Self;
50
51    fn sub(self, rhs: Duration) -> Self::Output {
52        Self::from_us(self.us - rhs.as_us())
53    }
54}
55
56impl core::ops::Sub for Duration {
57    type Output = Self;
58
59    fn sub(self, rhs: Duration) -> Self::Output {
60        Self::from_us(self.as_us() - rhs.as_us())
61    }
62}
63
64impl core::ops::Mul<usize> for Duration {
65    type Output = Self;
66
67    fn mul(self, rhs: usize) -> Self::Output {
68        Self::from_us(self.as_us() * rhs as i64)
69    }
70}
71
72impl core::ops::Add<Duration> for Instant {
73    type Output = Self;
74
75    fn add(self, rhs: Duration) -> Self::Output {
76        Self::from_us(self.us + rhs.as_us())
77    }
78}
79
80impl core::ops::Div<usize> for Duration {
81    type Output = Self;
82
83    fn div(self, rhs: usize) -> Self::Output {
84        Self::from_us(self.as_us() / rhs as i64)
85    }
86}
87
88impl core::ops::Add<Duration> for Duration {
89    type Output = Self;
90
91    fn add(self, rhs: Duration) -> Self::Output {
92        Self::from_us(self.as_us() + rhs.as_us())
93    }
94}
95
96#[cfg(test)]
97mod tests {
98    use super::*;
99
100    #[test]
101    fn instant() {
102        let a = Instant::from_us(100);
103        assert_eq!(a.us, 100);
104        assert_eq!(a.as_us(), 100);
105    }
106
107    #[test]
108    fn instant_operations() {
109        let a = Instant::from_us(100);
110        let b = Instant::from_us(50);
111        assert_eq!((a - b).as_us(), 50);
112        assert_eq!((a - Duration::from_us(50)).as_us(), 50);
113        assert_eq!((a + Duration::from_us(50)).as_us(), 150);
114    }
115
116    #[test]
117    fn duration() {
118        let a = Duration::from_us(100);
119        assert_eq!(a.0, 100);
120        assert_eq!(a.as_us(), 100);
121    }
122
123    #[test]
124    fn duration_operations() {
125        let a = Duration::from_us(100);
126        let b = Duration::from_us(50);
127        assert_eq!((a - b).as_us(), 50);
128        assert_eq!((a * 2).as_us(), 200);
129        assert_eq!((a / 2).as_us(), 50);
130        assert_eq!((a + b).as_us(), 150);
131    }
132}