1use std::ops::{Add, Sub};
2
3#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug)]
8pub struct Duration {
9 pub secs: u32,
10 pub micros: u32,
11}
12
13pub const MICROS_PER_SEC: u32 = 1_000_000;
14
15impl Duration {
16 pub fn new(secs: u32, micros: u32) -> Duration {
18 Duration { secs, micros }
19 }
20 #[inline]
22 pub fn is_null(self) -> bool {
23 self.secs == 0 && self.micros == 0
24 }
25}
26
27impl Add for Duration {
28 type Output = Duration;
29
30 #[allow(clippy::suspicious_arithmetic_impl)]
31 fn add(self, other: Duration) -> Self::Output {
32 let secs = self.secs.wrapping_add(other.secs);
33 let micros = self.micros.wrapping_add(other.micros);
34 let (secs, micros) = if micros > MICROS_PER_SEC {
35 (secs + (micros / MICROS_PER_SEC), micros % MICROS_PER_SEC)
36 } else {
37 (secs, micros)
38 };
39
40 Duration { secs, micros }
41 }
42}
43
44impl Sub for Duration {
45 type Output = Duration;
46
47 #[allow(clippy::suspicious_arithmetic_impl)]
48 fn sub(self, other: Duration) -> Self::Output {
49 let secs = self.secs.wrapping_sub(other.secs);
50 let (secs, micros) = if self.micros >= other.micros {
51 (secs, self.micros - other.micros)
52 } else {
53 let diff = other.micros.wrapping_sub(self.micros);
54 let secs_less = diff / MICROS_PER_SEC;
55 let micros = MICROS_PER_SEC - diff;
56 (secs.wrapping_sub(1 + secs_less), micros)
57 };
58
59 Duration { secs, micros }
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::Duration;
66 #[test]
67 fn duration_sub() {
68 let d1 = Duration::new(1234, 5678);
69 let d2 = Duration::new(1234, 6789);
70 let d = d2 - d1;
71 assert_eq!(d.secs, 0);
72 assert_eq!(d.micros, 1111);
73 }
74}