kittycad_measurements/
lib.rs1#![deny(warnings, missing_docs)]
10#![cfg_attr(not(feature = "std"), no_std)]
11
12#[cfg(not(feature = "std"))]
13use core::time;
14
15#[cfg(feature = "std")]
16use std::time;
17
18use core::f64::consts::PI;
19
20#[macro_use]
21mod measurement;
22pub use measurement::Measurement;
23
24pub mod length;
25pub use length::{Distance, Length};
26
27pub mod temperature;
28pub use temperature::{Temperature, TemperatureDelta};
29
30pub mod humidity;
31pub use humidity::Humidity;
32
33pub mod mass;
34pub use mass::Mass;
35
36pub mod volume;
37pub use volume::Volume;
38
39pub mod density;
40pub use density::Density;
41
42pub mod pressure;
43pub use pressure::Pressure;
44
45pub mod speed;
46pub use speed::Speed;
47
48pub mod acceleration;
49pub use acceleration::Acceleration;
50
51pub mod energy;
52pub use energy::Energy;
53
54pub mod power;
55pub use power::Power;
56
57pub mod voltage;
58pub use voltage::Voltage;
59
60pub mod current;
61pub use current::Current;
62
63pub mod resistance;
64pub use resistance::Resistance;
65
66pub mod force;
67pub use force::Force;
68
69pub mod area;
70pub use area::Area;
71
72pub mod angle;
73pub use angle::Angle;
74
75pub mod frequency;
76pub use frequency::Frequency;
77
78pub mod angular_velocity;
79pub use angular_velocity::AngularVelocity;
80
81pub mod torque;
82pub use torque::Torque;
83
84pub mod data;
85pub use data::Data;
86
87mod torque_energy;
88pub use torque_energy::TorqueEnergy;
89
90pub mod prelude;
91
92pub mod test_utils;
93
94macro_rules! impl_maths {
100 ($a:ty, $b:ty) => {
101 impl core::ops::Mul<$b> for $b {
102 type Output = $a;
103
104 fn mul(self, rhs: $b) -> Self::Output {
105 Self::Output::from_base_units(self.as_base_units() * rhs.as_base_units())
106 }
107 }
108
109 impl core::ops::Div<$b> for $a {
110 type Output = $b;
111
112 fn div(self, rhs: $b) -> Self::Output {
113 Self::Output::from_base_units(self.as_base_units() / rhs.as_base_units())
114 }
115 }
116 };
117
118 ($a:ty, $b:ty, $c:ty) => {
119 impl core::ops::Mul<$b> for $c {
120 type Output = $a;
121
122 fn mul(self, rhs: $b) -> Self::Output {
123 Self::Output::from_base_units(self.as_base_units() * rhs.as_base_units())
124 }
125 }
126
127 impl core::ops::Mul<$c> for $b {
128 type Output = $a;
129
130 fn mul(self, rhs: $c) -> Self::Output {
131 Self::Output::from_base_units(self.as_base_units() * rhs.as_base_units())
132 }
133 }
134
135 impl core::ops::Div<$c> for $a {
136 type Output = $b;
137
138 fn div(self, rhs: $c) -> Self::Output {
139 Self::Output::from_base_units(self.as_base_units() / rhs.as_base_units())
140 }
141 }
142
143 impl core::ops::Div<$b> for $a {
144 type Output = $c;
145
146 fn div(self, rhs: $b) -> Self::Output {
147 Self::Output::from_base_units(self.as_base_units() / rhs.as_base_units())
148 }
149 }
150 };
151}
152
153impl Measurement for time::Duration {
154 fn get_base_units_name(&self) -> &'static str {
155 "s"
156 }
157
158 fn as_base_units(&self) -> f64 {
159 self.as_secs() as f64 + (f64::from(self.subsec_nanos()) * 1e-9)
160 }
161
162 fn from_base_units(units: f64) -> Self {
163 let subsec_nanos = ((units * 1e9) % 1e9) as u32;
164 let secs = units as u64;
165 time::Duration::new(secs, subsec_nanos)
166 }
167}
168
169impl_maths!(Area, Length);
170impl_maths!(Energy, time::Duration, Power);
171impl_maths!(Force, Mass, Acceleration);
172impl_maths!(Force, Pressure, Area);
173impl_maths!(Length, time::Duration, Speed);
174impl_maths!(Power, Force, Speed);
175impl_maths!(Speed, time::Duration, Acceleration);
176impl_maths!(Volume, Length, Area);
177impl_maths!(Power, AngularVelocity, Torque);
178impl_maths!(Power, Voltage, Current);
179impl_maths!(Voltage, Resistance, Current);
180
181impl_maths!(TorqueEnergy, Force, Length);
185
186impl core::ops::Div<Length> for Torque {
190 type Output = Force;
191
192 fn div(self, rhs: Length) -> Self::Output {
193 Self::Output::from_base_units(self.as_base_units() / rhs.as_base_units())
194 }
195}
196
197impl core::ops::Div<Force> for Torque {
198 type Output = Length;
199
200 fn div(self, rhs: Force) -> Self::Output {
201 Self::Output::from_base_units(self.as_base_units() / rhs.as_base_units())
202 }
203}
204
205impl core::ops::Div<Length> for Energy {
206 type Output = Force;
207
208 fn div(self, rhs: Length) -> Self::Output {
209 Self::Output::from_base_units(self.as_base_units() / rhs.as_base_units())
210 }
211}
212
213impl core::ops::Div<Force> for Energy {
214 type Output = Length;
215
216 fn div(self, rhs: Force) -> Self::Output {
217 Self::Output::from_base_units(self.as_base_units() / rhs.as_base_units())
218 }
219}