Skip to main content

autd3_rs_core/common/
length.rs

1#[allow(non_camel_case_types)]
2pub struct m;
3
4#[allow(non_camel_case_types)]
5pub struct mm;
6
7#[derive(Clone, Copy, PartialEq, PartialOrd)]
8pub struct Length {
9    millimetres: f32,
10}
11
12impl core::fmt::Debug for Length {
13    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14        write!(f, "{} mm", self.millimetres)
15    }
16}
17
18impl Length {
19    #[must_use]
20    pub const fn from_mm(millimetres: f32) -> Self {
21        Self { millimetres }
22    }
23
24    #[must_use]
25    pub const fn from_m(metres: f32) -> Self {
26        Self {
27            millimetres: metres * 1000.0,
28        }
29    }
30
31    #[must_use]
32    pub const fn mm(self) -> f32 {
33        self.millimetres
34    }
35
36    #[must_use]
37    pub const fn m(self) -> f32 {
38        self.millimetres / 1000.0
39    }
40}
41
42impl core::ops::Mul<m> for f32 {
43    type Output = Length;
44    fn mul(self, _rhs: m) -> Self::Output {
45        Length {
46            millimetres: self * 1000.0,
47        }
48    }
49}
50
51impl core::ops::Mul<mm> for f32 {
52    type Output = Length;
53    fn mul(self, _rhs: mm) -> Self::Output {
54        Length { millimetres: self }
55    }
56}
57
58impl core::ops::Mul<m> for i32 {
59    type Output = Length;
60    fn mul(self, _rhs: m) -> Self::Output {
61        Length {
62            millimetres: self as f32 * 1000.0,
63        }
64    }
65}
66
67impl core::ops::Mul<mm> for i32 {
68    type Output = Length;
69    fn mul(self, _rhs: mm) -> Self::Output {
70        Length {
71            millimetres: self as f32,
72        }
73    }
74}
75
76impl core::ops::Mul<f32> for Length {
77    type Output = Length;
78    fn mul(self, rhs: f32) -> Self::Output {
79        Length {
80            millimetres: self.millimetres * rhs,
81        }
82    }
83}
84
85impl core::ops::Mul<Length> for f32 {
86    type Output = Length;
87    fn mul(self, rhs: Length) -> Self::Output {
88        Length {
89            millimetres: self * rhs.millimetres,
90        }
91    }
92}
93
94impl core::ops::Div<f32> for Length {
95    type Output = Length;
96    fn div(self, rhs: f32) -> Self::Output {
97        Length {
98            millimetres: self.millimetres / rhs,
99        }
100    }
101}
102
103impl core::ops::Add<Length> for Length {
104    type Output = Length;
105    fn add(self, rhs: Length) -> Self::Output {
106        Length {
107            millimetres: self.millimetres + rhs.millimetres,
108        }
109    }
110}
111
112impl core::ops::Sub<Length> for Length {
113    type Output = Length;
114    fn sub(self, rhs: Length) -> Self::Output {
115        Length {
116            millimetres: self.millimetres - rhs.millimetres,
117        }
118    }
119}
120
121impl core::ops::Neg for Length {
122    type Output = Length;
123    fn neg(self) -> Self::Output {
124        Length {
125            millimetres: -self.millimetres,
126        }
127    }
128}
129
130#[cfg(test)]
131mod tests {
132    use super::*;
133
134    #[test]
135    fn literals() {
136        approx::assert_abs_diff_eq!((1.0 * m).mm(), 1000.0);
137        approx::assert_abs_diff_eq!((10.0 * mm).mm(), 10.0);
138        approx::assert_abs_diff_eq!((150 * mm).mm(), 150.0);
139        approx::assert_abs_diff_eq!((2 * m).mm(), 2000.0);
140        approx::assert_abs_diff_eq!((0.15 * m).m(), 0.15);
141    }
142
143    #[test]
144    fn ops() {
145        approx::assert_abs_diff_eq!((2.0 * (3.0 * mm)).mm(), 6.0);
146        approx::assert_abs_diff_eq!(((3.0 * mm) * 2.0).mm(), 6.0);
147        approx::assert_abs_diff_eq!(((6.0 * mm) / 2.0).mm(), 3.0);
148        approx::assert_abs_diff_eq!((1.0 * mm + 2.0 * mm).mm(), 3.0);
149        approx::assert_abs_diff_eq!((3.0 * mm - 1.0 * mm).mm(), 2.0);
150        approx::assert_abs_diff_eq!((-(1.0 * mm)).mm(), -1.0);
151    }
152
153    #[test]
154    fn dbg() {
155        assert_eq!(format!("{:?}", 8.5 * mm), "8.5 mm");
156    }
157}