1use std::ops::{Add, AddAssign, Sub};
2
3#[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#[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}