microcad_lang/ty/
quantity_type.rs1use strum::IntoStaticStr;
7
8use crate::lower::ir;
9
10#[derive(Clone, Debug, IntoStaticStr, PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub enum QuantityType {
13 Scalar,
15 Length,
17 Area,
19 Volume,
21 Density,
23 Angle,
25 Weight,
27 Invalid,
29}
30
31impl QuantityType {
32 pub fn base_unit(&self) -> ir::Unit {
34 match self {
35 QuantityType::Scalar => ir::Unit::None,
36 QuantityType::Length => ir::Unit::Millimeter,
37 QuantityType::Area => ir::Unit::Millimeter2,
38 QuantityType::Volume => ir::Unit::Millimeter3,
39 QuantityType::Density => ir::Unit::GramPerMeter3,
40 QuantityType::Angle => ir::Unit::Rad,
41 QuantityType::Weight => ir::Unit::Gram,
42 QuantityType::Invalid => todo!(),
43 }
44 }
45}
46
47impl std::fmt::Display for QuantityType {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 let name: &'static str = self.into();
50 write!(f, "{name}")
51 }
52}
53
54impl std::ops::Mul for QuantityType {
55 type Output = QuantityType;
56
57 fn mul(self, rhs: Self) -> Self::Output {
58 if self == Self::Invalid || rhs == Self::Invalid {
59 return Self::Invalid;
60 }
61 if self == QuantityType::Scalar {
62 return rhs;
63 }
64 if rhs == QuantityType::Scalar {
65 return self;
66 }
67
68 match (self, rhs) {
69 (QuantityType::Length, QuantityType::Length) => QuantityType::Area,
70 (QuantityType::Length, QuantityType::Area)
71 | (QuantityType::Area, QuantityType::Length) => QuantityType::Volume,
72 (_, _) => QuantityType::Invalid,
73 }
74 }
75}
76
77impl std::ops::Div for QuantityType {
78 type Output = QuantityType;
79
80 fn div(self, rhs: Self) -> Self::Output {
81 if rhs == self {
82 return QuantityType::Scalar;
83 }
84 if rhs == QuantityType::Scalar {
85 return self;
86 }
87
88 match (self, rhs) {
89 (QuantityType::Area, QuantityType::Length)
90 | (QuantityType::Volume, QuantityType::Area) => QuantityType::Length,
91 (QuantityType::Volume, QuantityType::Length) => QuantityType::Area,
92 (_, _) => QuantityType::Invalid,
93 }
94 }
95}