1use core::ops::{Add, AddAssign, Sub, SubAssign};
4
5use crate::{Duration, NANOS_PER_MICRO, NANOS_PER_MILLI, NANOS_PER_SEC};
6
7#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14pub struct Instant(u64);
15
16impl Instant {
17 pub const ZERO: Self = Self(0);
19 pub const MAX: Self = Self(u64::MAX);
21
22 #[must_use]
24 pub const fn from_nanos(nanos: u64) -> Self {
25 Self(nanos)
26 }
27
28 #[must_use]
31 pub const fn from_micros(micros: u64) -> Self {
32 Self(micros.saturating_mul(NANOS_PER_MICRO))
33 }
34
35 #[must_use]
38 pub const fn from_millis(millis: u64) -> Self {
39 Self(millis.saturating_mul(NANOS_PER_MILLI))
40 }
41
42 #[must_use]
45 pub const fn from_secs(secs: u64) -> Self {
46 Self(secs.saturating_mul(NANOS_PER_SEC))
47 }
48
49 #[must_use]
51 pub const fn as_nanos(self) -> u64 {
52 self.0
53 }
54
55 #[must_use]
57 pub const fn as_micros(self) -> u64 {
58 self.since_epoch().as_micros()
59 }
60
61 #[must_use]
63 pub const fn as_millis(self) -> u64 {
64 self.since_epoch().as_millis()
65 }
66
67 #[must_use]
69 pub const fn as_secs(self) -> u64 {
70 self.since_epoch().as_secs()
71 }
72
73 #[must_use]
75 pub const fn checked_add(self, duration: Duration) -> Option<Self> {
76 match self.0.checked_add(duration.as_nanos()) {
77 Some(nanos) => Some(Self(nanos)),
78 None => None,
79 }
80 }
81
82 #[must_use]
84 pub const fn saturating_add(self, duration: Duration) -> Self {
85 Self(self.0.saturating_add(duration.as_nanos()))
86 }
87
88 #[must_use]
90 pub const fn checked_sub(self, duration: Duration) -> Option<Self> {
91 match self.0.checked_sub(duration.as_nanos()) {
92 Some(nanos) => Some(Self(nanos)),
93 None => None,
94 }
95 }
96
97 #[must_use]
99 pub const fn saturating_sub(self, duration: Duration) -> Self {
100 Self(self.0.saturating_sub(duration.as_nanos()))
101 }
102
103 #[must_use]
105 pub const fn checked_duration_since(self, earlier: Self) -> Option<Duration> {
106 match self.0.checked_sub(earlier.0) {
107 Some(nanos) => Some(Duration::from_nanos(nanos)),
108 None => None,
109 }
110 }
111
112 #[must_use]
114 pub const fn saturating_duration_since(self, earlier: Self) -> Duration {
115 Duration::from_nanos(self.0.saturating_sub(earlier.0))
116 }
117
118 #[must_use]
121 pub const fn min(self, other: Self) -> Self {
122 if self.0 <= other.0 {
123 self
124 } else {
125 other
126 }
127 }
128
129 #[must_use]
131 pub const fn max(self, other: Self) -> Self {
132 if self.0 >= other.0 {
133 self
134 } else {
135 other
136 }
137 }
138
139 const fn since_epoch(self) -> Duration {
141 Duration::from_nanos(self.0)
142 }
143}
144
145impl Add<Duration> for Instant {
146 type Output = Self;
147
148 fn add(self, rhs: Duration) -> Self {
150 self.saturating_add(rhs)
151 }
152}
153
154impl AddAssign<Duration> for Instant {
155 fn add_assign(&mut self, rhs: Duration) {
157 *self = self.saturating_add(rhs);
158 }
159}
160
161impl Sub<Duration> for Instant {
162 type Output = Self;
163
164 fn sub(self, rhs: Duration) -> Self {
166 self.saturating_sub(rhs)
167 }
168}
169
170impl SubAssign<Duration> for Instant {
171 fn sub_assign(&mut self, rhs: Duration) {
173 *self = self.saturating_sub(rhs);
174 }
175}
176
177impl Sub for Instant {
178 type Output = Duration;
179
180 fn sub(self, rhs: Self) -> Duration {
182 self.saturating_duration_since(rhs)
183 }
184}