1use kittycad_unit_conversion_derive::UnitConversion;
2use parse_display_derive::Display;
3use parse_display_derive::FromStr;
4use schemars::JsonSchema;
5use serde::Deserialize;
6use serde::Serialize;
7use ts_rs::TS;
8
9#[derive(
11 Default,
12 Display,
13 FromStr,
14 Copy,
15 Eq,
16 PartialEq,
17 Debug,
18 JsonSchema,
19 Deserialize,
20 Serialize,
21 Clone,
22 Ord,
23 PartialOrd,
24 UnitConversion,
25 Hash,
26 TS,
27)]
28#[display(style = "snake_case")]
29#[ts(export_to = "ModelingCmd.ts")]
30#[cfg_attr(
31 feature = "pyo3",
32 pyo3::pyclass(eq, from_py_object),
33 pyo3_stub_gen::derive::gen_stub_pyclass_enum
34)]
35pub enum UnitLength {
36 #[serde(rename = "cm")]
38 #[display("cm")]
39 Centimeters,
40 #[serde(rename = "ft")]
42 #[display("ft")]
43 Feet,
44 #[serde(rename = "in")]
46 #[display("in")]
47 Inches,
48 #[default]
50 #[serde(rename = "m")]
51 #[display("m")]
52 Meters,
53 #[serde(rename = "mm")]
55 #[display("mm")]
56 Millimeters,
57 #[serde(rename = "yd")]
59 #[display("yd")]
60 Yards,
61}
62
63impl UnitLength {
64 pub fn as_measurement(self, value: f64) -> measurements::Length {
66 match self {
67 Self::Centimeters => measurements::Length::from_centimeters(value),
68 Self::Feet => measurements::Length::from_feet(value),
69 Self::Inches => measurements::Length::from_inches(value),
70 Self::Meters => measurements::Length::from_meters(value),
71 Self::Millimeters => measurements::Length::from_millimeters(value),
72 Self::Yards => measurements::Length::from_yards(value),
73 }
74 }
75}
76
77#[derive(
79 Default,
80 Display,
81 FromStr,
82 Copy,
83 Eq,
84 PartialEq,
85 Debug,
86 JsonSchema,
87 Deserialize,
88 Serialize,
89 Clone,
90 Ord,
91 PartialOrd,
92 UnitConversion,
93 Hash,
94 TS,
95)]
96#[serde(rename_all = "snake_case")]
97#[display(style = "snake_case")]
98#[ts(export_to = "ModelingCmd.ts")]
99#[cfg_attr(
100 feature = "pyo3",
101 pyo3::pyclass(eq, from_py_object),
102 pyo3_stub_gen::derive::gen_stub_pyclass_enum
103)]
104pub enum UnitAngle {
105 #[default]
107 #[display("deg")]
108 Degrees,
109 #[display("rad")]
111 Radians,
112}
113
114#[derive(
116 Display,
117 FromStr,
118 Copy,
119 Eq,
120 PartialEq,
121 Debug,
122 JsonSchema,
123 Deserialize,
124 Serialize,
125 Clone,
126 Ord,
127 PartialOrd,
128 UnitConversion,
129 Default,
130 Hash,
131 TS,
132)]
133#[serde(rename_all = "snake_case")]
134#[display(style = "snake_case")]
135#[ts(export_to = "ModelingCmd.ts")]
136#[cfg_attr(
137 feature = "pyo3",
138 pyo3::pyclass(eq, from_py_object),
139 pyo3_stub_gen::derive::gen_stub_pyclass_enum
140)]
141pub enum UnitArea {
142 #[serde(rename = "cm2")]
144 #[display("cm2")]
145 SquareCentimeters,
146 #[serde(rename = "dm2")]
148 #[display("dm2")]
149 SquareDecimeters,
150 #[serde(rename = "ft2")]
152 #[display("ft2")]
153 SquareFeet,
154 #[serde(rename = "in2")]
156 #[display("in2")]
157 SquareInches,
158 #[serde(rename = "km2")]
160 #[display("km2")]
161 SquareKilometers,
162 #[default]
164 #[serde(rename = "m2")]
165 #[display("m2")]
166 SquareMeters,
167 #[serde(rename = "mm2")]
169 #[display("mm2")]
170 SquareMillimeters,
171 #[serde(rename = "yd2")]
173 #[display("yd2")]
174 SquareYards,
175}
176
177impl UnitArea {
178 pub fn as_measurement(self, value: f64) -> measurements::Area {
180 match self {
181 Self::SquareCentimeters => measurements::Area::from_square_centimeters(value),
182 Self::SquareDecimeters => measurements::Area::from_square_decimeters(value),
183 Self::SquareFeet => measurements::Area::from_square_feet(value),
184 Self::SquareInches => measurements::Area::from_square_inches(value),
185 Self::SquareKilometers => measurements::Area::from_square_kilometers(value),
186 Self::SquareMeters => measurements::Area::from_square_meters(value),
187 Self::SquareMillimeters => measurements::Area::from_square_millimeters(value),
188 Self::SquareYards => measurements::Area::from_square_yards(value),
189 }
190 }
191}
192
193#[derive(
195 Display,
196 Copy,
197 Eq,
198 PartialEq,
199 Debug,
200 JsonSchema,
201 Deserialize,
202 Serialize,
203 Clone,
204 Ord,
205 PartialOrd,
206 Default,
207 UnitConversion,
208 Hash,
209 TS,
210)]
211#[display(style = "snake_case")]
212#[ts(export_to = "ModelingCmd.ts")]
213#[cfg_attr(
214 feature = "pyo3",
215 pyo3::pyclass(eq, from_py_object),
216 pyo3_stub_gen::derive::gen_stub_pyclass_enum
217)]
218pub enum UnitDensity {
219 #[serde(rename = "lb:ft3")]
221 #[display("lb:ft3")]
222 PoundsPerCubicFeet,
223
224 #[default]
226 #[serde(rename = "kg:m3")]
227 #[display("kg:m3")]
228 KilogramsPerCubicMeter,
229}
230
231impl std::str::FromStr for UnitDensity {
232 type Err = parse_display::ParseError;
233
234 fn from_str(s: &str) -> Result<Self, Self::Err> {
235 match s {
236 "lbft3" | "lb:ft3" | "lb-ft3" => Ok(Self::PoundsPerCubicFeet),
237 "kgm3" | "kg:m3" | "kg-m3" => Ok(Self::KilogramsPerCubicMeter),
238 _other => Err(Default::default()),
239 }
240 }
241}
242
243impl UnitDensity {
244 pub fn as_measurement(self, value: f64) -> measurements::Density {
246 match self {
247 Self::PoundsPerCubicFeet => measurements::Density::from_pounds_per_cubic_feet(value),
248 Self::KilogramsPerCubicMeter => measurements::Density::from_kilograms_per_cubic_meter(value),
249 }
250 }
251}
252
253#[derive(
255 Default,
256 Display,
257 FromStr,
258 Copy,
259 Eq,
260 PartialEq,
261 Debug,
262 JsonSchema,
263 Deserialize,
264 Serialize,
265 Clone,
266 Ord,
267 PartialOrd,
268 UnitConversion,
269 Hash,
270 TS,
271)]
272#[serde(rename_all = "snake_case")]
273#[display(style = "snake_case")]
274#[ts(export_to = "ModelingCmd.ts")]
275#[cfg_attr(
276 feature = "pyo3",
277 pyo3::pyclass(eq, from_py_object),
278 pyo3_stub_gen::derive::gen_stub_pyclass_enum
279)]
280pub enum UnitMass {
281 #[default]
283 #[serde(rename = "g")]
284 #[display("g")]
285 Grams,
286 #[serde(rename = "kg")]
288 #[display("kg")]
289 Kilograms,
290 #[serde(rename = "lb")]
292 #[display("lb")]
293 Pounds,
294}
295
296impl UnitMass {
297 pub fn as_measurement(self, value: f64) -> measurements::Mass {
299 match self {
300 Self::Grams => measurements::Mass::from_grams(value),
301 Self::Kilograms => measurements::Mass::from_kilograms(value),
302 Self::Pounds => measurements::Mass::from_pounds(value),
303 }
304 }
305}
306
307#[derive(
309 Default,
310 Display,
311 FromStr,
312 Copy,
313 Eq,
314 PartialEq,
315 Debug,
316 JsonSchema,
317 Deserialize,
318 Serialize,
319 Clone,
320 Ord,
321 PartialOrd,
322 UnitConversion,
323 Hash,
324 TS,
325)]
326#[display(style = "snake_case")]
327#[ts(export_to = "ModelingCmd.ts")]
328#[cfg_attr(
329 feature = "pyo3",
330 pyo3::pyclass(eq, from_py_object),
331 pyo3_stub_gen::derive::gen_stub_pyclass_enum
332)]
333pub enum UnitVolume {
334 #[serde(rename = "mm3")]
336 #[display("mm3")]
337 CubicMillimeters,
338 #[serde(rename = "cm3")]
340 #[display("cm3")]
341 CubicCentimeters,
342 #[serde(rename = "ft3")]
344 #[display("ft3")]
345 CubicFeet,
346 #[serde(rename = "in3")]
348 #[display("in3")]
349 CubicInches,
350 #[default]
352 #[serde(rename = "m3")]
353 #[display("m3")]
354 CubicMeters,
355 #[serde(rename = "yd3")]
357 #[display("yd3")]
358 CubicYards,
359 #[serde(rename = "usfloz")]
361 #[display("usfloz")]
362 FluidOunces,
363 #[serde(rename = "usgal")]
365 #[display("usgal")]
366 Gallons,
367 #[serde(rename = "l")]
369 #[display("l")]
370 Liters,
371 #[serde(rename = "ml")]
373 #[display("ml")]
374 Milliliters,
375}
376
377impl UnitVolume {
378 pub fn as_measurement(self, value: f64) -> measurements::Volume {
380 match self {
381 Self::CubicMillimeters => measurements::Volume::from_cubic_millimeters(value),
382 Self::CubicCentimeters => measurements::Volume::from_cubic_centimeters(value),
383 Self::CubicFeet => measurements::Volume::from_cubic_feet(value),
384 Self::CubicInches => measurements::Volume::from_cubic_inches(value),
385 Self::CubicMeters => measurements::Volume::from_cubic_meters(value),
386 Self::CubicYards => measurements::Volume::from_cubic_yards(value),
387 Self::FluidOunces => measurements::Volume::from_fluid_ounces(value),
388 Self::Gallons => measurements::Volume::from_gallons(value),
389 Self::Liters => measurements::Volume::from_liters(value),
390 Self::Milliliters => measurements::Volume::from_milliliters(value),
391 }
392 }
393}