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