rta_for_fps_lib/
time.rs

1//! Module defining a Unit of Time
2
3use core::fmt::{Debug, Formatter};
4use core::iter::Sum;
5use core::ops::{Add, AddAssign, Div, Mul, Sub};
6
7mod util {
8    //! Utility Module for the time module
9
10    /// Calculate the least common multiple
11    pub(crate) const fn lcm(a: super::UnitNumber, b: super::UnitNumber) -> super::UnitNumber {
12        if a == b {
13            a
14        } else {
15            a * b / gcd(a, b)
16        }
17    }
18
19    /// Calculate the greatest common divisor
20    const fn gcd(mut a: super::UnitNumber, mut b: super::UnitNumber) -> super::UnitNumber {
21        while a != b {
22            if a > b {
23                a -= b
24            } else {
25                b -= a
26            }
27        }
28        a
29    }
30}
31
32/// The type that represents a unit-less unsigned number
33pub type UnitNumber = usize;
34
35/// The Type representing some Units of Time
36#[derive(Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
37pub struct TimeUnit(UnitNumber);
38
39impl Debug for TimeUnit {
40    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
41        core::fmt::Debug::fmt(&self.0, f)
42    }
43}
44
45impl TimeUnit {
46    /// Zero Units of Time
47    pub const ZERO: TimeUnit = TimeUnit(0);
48
49    /// One Unit of Time
50    pub const ONE: TimeUnit = TimeUnit(1);
51
52    /// Get the longer/maximal Unit of Time
53    #[must_use]
54    pub fn max(self, other: Self) -> Self {
55        TimeUnit(self.0.max(other.0))
56    }
57
58    /// Calculate the least common multiple
59    #[must_use]
60    pub const fn lcm(self, other: Self) -> Self {
61        TimeUnit(util::lcm(self.0, other.0))
62    }
63
64    /// Get the Numeric Value of the `TimeUnit` as a `UnitNumber`
65    #[must_use]
66    pub const fn as_unit(self) -> UnitNumber {
67        self.0
68    }
69}
70
71impl From<UnitNumber> for TimeUnit {
72    fn from(time: UnitNumber) -> Self {
73        TimeUnit(time)
74    }
75}
76
77impl Div for TimeUnit {
78    type Output = UnitNumber;
79
80    fn div(self, rhs: Self) -> Self::Output {
81        self.0 / rhs.0
82    }
83}
84
85impl Mul<TimeUnit> for UnitNumber {
86    type Output = TimeUnit;
87
88    fn mul(self, rhs: TimeUnit) -> Self::Output {
89        TimeUnit(self * rhs.0)
90    }
91}
92
93impl Mul<UnitNumber> for TimeUnit {
94    type Output = TimeUnit;
95
96    fn mul(self, rhs: UnitNumber) -> Self::Output {
97        TimeUnit(self.0 * rhs)
98    }
99}
100
101impl Add for TimeUnit {
102    type Output = TimeUnit;
103
104    fn add(self, rhs: Self) -> Self::Output {
105        TimeUnit(self.0 + rhs.0)
106    }
107}
108
109impl AddAssign for TimeUnit {
110    fn add_assign(&mut self, rhs: Self) {
111        self.0 += rhs.0
112    }
113}
114
115impl AsRef<TimeUnit> for TimeUnit {
116    fn as_ref(&self) -> &TimeUnit {
117        self
118    }
119}
120
121impl<T: AsRef<TimeUnit>> Sub<T> for TimeUnit {
122    type Output = TimeUnit;
123
124    fn sub(self, rhs: T) -> Self::Output {
125        TimeUnit(self.0 - rhs.as_ref().0)
126    }
127}
128
129impl Sum for TimeUnit {
130    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
131        iter.fold(TimeUnit::from(0), Self::add)
132    }
133}