1pub mod prelude {
18 pub use super::{
19 Time,
20 Time2,
21 };
22}
23
24#[derive(Debug)]
25#[derive(Clone, Copy)]
26pub struct Time {
27 pub value_ns: f64,
28}
29
30#[derive(Debug)]
31#[derive(Clone, Copy)]
32pub struct Time2 {
33 pub value_ns_2: f64,
34}
35
36impl Time {
39 pub const MICRO_TO_NANO: f64 = 1000.0;
40 pub const MILLI_TO_NANO: f64 = 1000_000.0;
41 pub const SECS_TO_NANO: f64 = 1000_000_000.0;
42
43 pub fn zero() -> Self {
44 Self { value_ns: 0.0 }
45 }
46
47 pub fn one() -> Self {
48 Self { value_ns: 1.0 }
49 }
50
51 pub fn nanos(time_ns: f64) -> Self {
52 Self { value_ns: time_ns }
53 }
54
55 pub fn micros(time_us: f64) -> Self {
56 Self { value_ns: time_us * Self::MICRO_TO_NANO }
57 }
58
59 pub fn millis(time_ms: f64) -> Self {
60 Self { value_ns: time_ms * Self::MILLI_TO_NANO }
61 }
62
63 pub fn secs(time_s: f64) -> Self {
64 Self { value_ns: time_s * Self::SECS_TO_NANO }
65 }
66
67 pub fn as_nanos(&self) -> f64 {
68 self.value_ns
69 }
70
71 pub fn as_micros(&self) -> f64 {
72 self.value_ns / Self::MICRO_TO_NANO
73 }
74
75 pub fn as_millis(&self) -> f64 {
76 self.value_ns / Self::MILLI_TO_NANO
77 }
78
79 pub fn as_secs(&self) -> f64 {
80 self.value_ns / Self::SECS_TO_NANO
81 }
82
83 pub fn floor(self) -> Self {
84 Self { value_ns: f64::floor(self.value_ns) }
85 }
86
87 pub fn ceil(self) -> Self {
88 Self { value_ns: f64::ceil(self.value_ns) }
89 }
90
91 pub fn round(self) -> Self {
92 Self { value_ns: f64::round(self.value_ns) }
93 }
94}
95
96impl PartialEq for Time {
97 fn eq(&self, other: &Self) -> bool {
98 let error = 0.5;
99
100 f64::abs(self.value_ns - other.value_ns) < error
101 }
102}
103
104impl Eq for Time { }
105
106impl PartialOrd for Time {
107 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
108 ordered_float::OrderedFloat(self.value_ns)
109 .partial_cmp(&ordered_float::OrderedFloat(other.value_ns))
110 }
111}
112
113impl Ord for Time {
114 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
115 ordered_float::OrderedFloat(self.value_ns)
116 .cmp(&ordered_float::OrderedFloat(other.value_ns))
117 }
118}
119
120impl std::ops::Neg for Time {
121 type Output = Time;
122
123 fn neg(self) -> Self::Output {
124 Self::Output { value_ns: -self.value_ns }
125 }
126}
127
128impl std::ops::Add for Time {
129 type Output = Time;
130
131 fn add(self, rhs: Self) -> Self::Output {
132 Self::Output { value_ns: (self.value_ns + rhs.value_ns) }
133 }
134}
135
136impl std::ops::Sub for Time {
137 type Output = Time;
138
139 fn sub(self, rhs: Self) -> Self::Output {
140 Self::Output { value_ns: (self.value_ns - rhs.value_ns) }
141 }
142}
143
144impl std::ops::Mul<f64> for Time {
145 type Output = Time;
146
147 fn mul(self, rhs: f64) -> Self::Output {
148 Self::Output { value_ns: (self.value_ns * rhs) }
149 }
150}
151
152impl std::ops::Mul<Time> for f64 {
153 type Output = Time;
154
155 fn mul(self, rhs: Time) -> Self::Output {
156 rhs * self
157 }
158}
159
160impl std::ops::Div for Time {
161 type Output = f64;
162
163 fn div(self, rhs: Self) -> Self::Output {
164 self.value_ns / rhs.value_ns
165 }
166}
167
168impl std::ops::Div<f64> for Time {
169 type Output = Time;
170
171 fn div(self, rhs: f64) -> Self::Output {
172 Time { value_ns: self.value_ns / rhs }
173 }
174}
175
176impl std::ops::Rem for Time {
177 type Output = Time;
178
179 fn rem(self, rhs: Self) -> Self::Output {
180 Self::Output { value_ns: self.value_ns.floor() % rhs.value_ns.floor() }
181 }
182}
183
184impl std::iter::Sum for Time {
185 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
186 iter.fold(Time::zero(), |acc, val| acc + val)
187 }
188}
189
190impl std::fmt::Display for Time {
191 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
192 let milli = self.value_ns / Self::MILLI_TO_NANO;
193 if milli >= 1.0 {
194 return write!(f, "{milli:.3}ms");
195 }
196
197 let micro = self.value_ns / Self::MICRO_TO_NANO;
198 if micro >= 1.0 {
199 return write!(f, "{micro:.3}us");
200 }
201
202 write!(f, "{:.3}ns", self.value_ns)
203 }
204}
205
206impl serde::Serialize for Time {
207 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
208 where
209 S: serde::Serializer,
210 {
211 format!("{} ns", self.value_ns).serialize(serializer)
212 }
213}
214
215impl<'de> serde::Deserialize<'de> for Time {
216 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
217 where
218 D: serde::Deserializer<'de>,
219 {
220 let time_string = String::deserialize(deserializer)?;
221
222 let pieces: Vec<_> = time_string.trim().split_whitespace().collect();
223 if pieces.len() == 1 {
224 let time: f64 = pieces[0].parse()
225 .map_err(|err| serde::de::Error::custom(format!("Invalid time: {err}")))?;
226
227 Ok(Time { value_ns: time })
228 } else if pieces.len() == 2 {
229 let time: f64 = pieces[0].parse()
230 .map_err(|err| serde::de::Error::custom(format!("Invalid time: {err}")))?;
231 let unit = match pieces[1] {
232 "s" => Time::SECS_TO_NANO,
233 "ms" => Time::MILLI_TO_NANO,
234 "us" => Time::MICRO_TO_NANO,
235 "ns" => 1.0,
236 u => { return Err(serde::de::Error::custom(format!("Unknown time unit: {u}"))); }
237 };
238
239 Ok(Time::nanos(time * unit))
240 } else {
241 return Err(serde::de::Error::custom("Parsing error, unknown format"));
242 }
243 }
244}
245
246impl Time2 {
247 pub fn new(value: f64) -> Self {
248 Self { value_ns_2: value }
249 }
250
251 pub fn value(&self) -> f64 {
252 self.value_ns_2
253 }
254
255 pub fn sqrt(self) -> Time {
256 Time::nanos(self.value_ns_2.sqrt())
257 }
258}
259
260impl std::ops::Neg for Time2 {
261 type Output = Time2;
262
263 fn neg(self) -> Self::Output {
264 Self::Output { value_ns_2: -self.value_ns_2 }
265 }
266}
267
268impl std::ops::Add for Time2 {
269 type Output = Time2;
270
271 fn add(self, rhs: Self) -> Self::Output {
272 Self::Output { value_ns_2: (self.value_ns_2 + rhs.value_ns_2) }
273 }
274}
275
276impl std::ops::Sub for Time2 {
277 type Output = Time2;
278
279 fn sub(self, rhs: Self) -> Self::Output {
280 Self::Output { value_ns_2: (self.value_ns_2 - rhs.value_ns_2) }
281 }
282}
283
284impl std::ops::Mul<Time> for Time {
285 type Output = Time2;
286
287 fn mul(self, rhs: Time) -> Self::Output {
288 Self::Output { value_ns_2: (self.value_ns * rhs.value_ns) }
289 }
290}
291
292impl std::ops::Mul<f64> for Time2 {
293 type Output = Time2;
294
295 fn mul(self, rhs: f64) -> Self::Output {
296 Self::Output { value_ns_2: (self.value_ns_2 * rhs) }
297 }
298}
299
300impl std::ops::Mul<Time2> for f64 {
301 type Output = Time2;
302
303 fn mul(self, rhs: Time2) -> Self::Output {
304 rhs * self
305 }
306}
307
308impl std::ops::Div<Time> for Time2 {
309 type Output = Time;
310
311 fn div(self, rhs: Time) -> Self::Output {
312 Self::Output { value_ns: self.value_ns_2 / rhs.value_ns }
313 }
314}
315
316impl std::ops::Div<f64> for Time2 {
317 type Output = Time2;
318
319 fn div(self, rhs: f64) -> Self::Output {
320 Self::Output { value_ns_2: self.value_ns_2 / rhs }
321 }
322}