1use crate::ty::*;
7
8#[derive(Default, Clone, Debug, Copy, PartialEq, Eq, PartialOrd, Ord)]
10pub enum Unit {
11 #[default]
14 None,
15 Percent,
17
18 Meter,
21 Centimeter,
23 Millimeter,
25 Micrometer,
27 Inch,
29 Foot,
31 Yard,
33
34 Deg,
37 DegS,
39 Grad,
41 Turns,
43 Rad,
45
46 Gram,
49 Kilogram,
51 Pound,
53 Ounce,
55
56 Meter2,
59 Centimeter2,
61 Millimeter2,
63 Micrometer2,
65 Inch2,
67 Foot2,
69 Yard2,
71
72 Meter3,
75 Centimeter3,
77 Millimeter3,
79 Micrometer3,
81 Inch3,
83 Foot3,
85 Yard3,
87 Liter,
89 Centiliter,
91 Milliliter,
93 Microliter,
95
96 GramPerMeter3,
98 GramPerMillimeter3,
100}
101
102impl std::fmt::Display for Unit {
103 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
104 match self {
105 Self::None => write!(f, ""),
107 Self::Percent => write!(f, "%"),
108
109 Self::Meter => write!(f, "m"),
111 Self::Centimeter => write!(f, "cm"),
112 Self::Millimeter => write!(f, "mm"),
113 Self::Micrometer => write!(f, "µm"),
114 Self::Inch => write!(f, "in"),
115 Self::Foot => write!(f, "ft"),
116 Self::Yard => write!(f, "yd"),
117
118 Self::Deg => write!(f, "deg"),
120 Self::DegS => write!(f, "°"),
121 Self::Grad => write!(f, "grad"),
122 Self::Turns => write!(f, "turns"),
123 Self::Rad => write!(f, "rad"),
124
125 Self::Gram => write!(f, "g"),
127 Self::Kilogram => write!(f, "kg"),
128 Self::Pound => write!(f, "lb"),
129 Self::Ounce => write!(f, "oz"),
130
131 Self::Meter2 => write!(f, "m³"),
133 Self::Centimeter2 => write!(f, "cm²"),
134 Self::Millimeter2 => write!(f, "mm²"),
135 Self::Micrometer2 => write!(f, "µm²"),
136 Self::Inch2 => write!(f, "in²"),
137 Self::Foot2 => write!(f, "ft²"),
138 Self::Yard2 => write!(f, "yd²"),
139
140 Self::Meter3 => write!(f, "m³"),
142 Self::Centimeter3 => write!(f, "cm³"),
143 Self::Millimeter3 => write!(f, "mm³"),
144 Self::Micrometer3 => write!(f, "µm³"),
145 Self::Inch3 => write!(f, "in³"),
146 Self::Foot3 => write!(f, "ft³"),
147 Self::Yard3 => write!(f, "yd³"),
148
149 Self::Milliliter => write!(f, "ml"),
150 Self::Centiliter => write!(f, "cl"),
151 Self::Liter => write!(f, "l"),
152 Self::Microliter => write!(f, "µl"),
153
154 Self::GramPerMeter3 => write!(f, "g/m³"),
156 Self::GramPerMillimeter3 => write!(f, "g/mm³"),
157 }
158 }
159}
160
161impl Ty for Unit {
162 fn ty(&self) -> Type {
164 Type::Quantity(self.quantity_type())
165 }
166}
167
168impl Unit {
169 pub fn quantity_type(&self) -> QuantityType {
170 match self {
171 Self::None | Self::Percent => QuantityType::Scalar,
172 Self::Meter
173 | Self::Centimeter
174 | Self::Millimeter
175 | Self::Micrometer
176 | Self::Inch
177 | Self::Foot
178 | Self::Yard => QuantityType::Length,
179 Self::Deg | Self::DegS | Self::Grad | Self::Turns | Self::Rad => QuantityType::Angle,
180 Self::Gram | Self::Kilogram | Self::Pound | Self::Ounce => QuantityType::Weight,
181 Self::Meter2
182 | Self::Centimeter2
183 | Self::Millimeter2
184 | Self::Micrometer2
185 | Self::Inch2
186 | Self::Foot2
187 | Self::Yard2 => QuantityType::Area,
188 Self::Meter3
189 | Self::Centimeter3
190 | Self::Millimeter3
191 | Self::Micrometer3
192 | Self::Inch3
193 | Self::Foot3
194 | Self::Yard3
195 | Self::Liter
196 | Self::Centiliter
197 | Self::Milliliter
198 | Self::Microliter => QuantityType::Volume,
199 Self::GramPerMeter3 | Self::GramPerMillimeter3 => QuantityType::Density,
200 }
201 }
202
203 pub fn factor(&self) -> f64 {
204 match &self {
205 Self::None => 1.0,
207 Self::Percent => 0.01_f64,
208
209 Self::Meter => 1_000_f64,
211 Self::Centimeter => 10_f64,
212 Self::Millimeter => 1.0,
213 Self::Micrometer => 1.0 / 1_000_f64,
214 Self::Inch => 25.4_f64,
215 Self::Foot => 304.8_f64,
216 Self::Yard => 914.4_f64,
217
218 Self::Deg | Self::DegS => 1.0 / 180. * std::f64::consts::PI,
220 Self::Grad => 1.0 / 200. * std::f64::consts::PI,
221 Self::Turns => 2.0 * std::f64::consts::PI,
222 Self::Rad => 1.0,
223
224 Self::Gram => 1.0,
226 Self::Kilogram => 1_000_f64,
227 Self::Pound => 453.59237_f64,
228 Self::Ounce => 28.349_523_125_f64,
229
230 Self::Meter2 => 1_000_000_f64,
232 Self::Centimeter2 => 100_f64,
233 Self::Millimeter2 => 1.0,
234 Self::Micrometer2 => 0.000_000_1,
235 Self::Inch2 => 645.16_f64,
236 Self::Foot2 => 92_903_043.04_f64,
237 Self::Yard2 => 836_127.36_f64,
238
239 Self::Meter3 => 1_000_000_000_f64,
241 Self::Centimeter3 => 1_000_f64,
242 Self::Millimeter3 => 1.0,
243 Self::Micrometer3 => 0.000_000_000_1,
244 Self::Inch3 => 16_387.06_f64,
245 Self::Foot3 => 28_316_846.592_f64,
246 Self::Yard3 => 764_554_857.984_f64,
247 Self::Liter => 1_000_000_f64,
248 Self::Centiliter => 10_000_f64,
249 Self::Milliliter => 1_000_f64,
250 Self::Microliter => 1_000_000.0_f64,
251
252 Self::GramPerMeter3 => 1_000_000_000_f64,
254 Self::GramPerMillimeter3 => 1_f64,
255 }
256 }
257
258 pub fn normalize(self, x: f64) -> f64 {
260 x * self.factor()
261 }
262
263 pub fn denormalize(self, x: f64) -> f64 {
265 x / self.factor()
266 }
267}