Skip to main content

kcl_api/
numeric_suffix.rs

1use core::fmt;
2use std::str::FromStr;
3
4use kcl_error::CompilationIssue;
5use kcl_error::SourceRange;
6use serde::Deserialize;
7use serde::Serialize;
8
9use crate::NumericType;
10use crate::UnitAngle;
11use crate::UnitLength;
12use crate::UnitType;
13
14#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, ts_rs::TS)]
15#[repr(u32)]
16pub enum NumericSuffix {
17    None,
18    Count,
19    Length,
20    Angle,
21    Mm,
22    Cm,
23    M,
24    Inch,
25    Ft,
26    Yd,
27    Deg,
28    Rad,
29    Unknown,
30}
31
32impl NumericSuffix {
33    #[allow(dead_code)]
34    pub fn is_none(self) -> bool {
35        self == Self::None
36    }
37
38    pub fn is_some(self) -> bool {
39        self != Self::None
40    }
41
42    pub fn digestable_id(&self) -> &[u8] {
43        match self {
44            NumericSuffix::None => &[],
45            NumericSuffix::Count => b"_",
46            NumericSuffix::Unknown => b"?",
47            NumericSuffix::Length => b"Length",
48            NumericSuffix::Angle => b"Angle",
49            NumericSuffix::Mm => b"mm",
50            NumericSuffix::Cm => b"cm",
51            NumericSuffix::M => b"m",
52            NumericSuffix::Inch => b"in",
53            NumericSuffix::Ft => b"ft",
54            NumericSuffix::Yd => b"yd",
55            NumericSuffix::Deg => b"deg",
56            NumericSuffix::Rad => b"rad",
57        }
58    }
59}
60
61impl FromStr for NumericSuffix {
62    type Err = CompilationIssue;
63
64    fn from_str(s: &str) -> Result<Self, Self::Err> {
65        match s {
66            "_" | "Count" => Ok(NumericSuffix::Count),
67            "Length" => Ok(NumericSuffix::Length),
68            "Angle" => Ok(NumericSuffix::Angle),
69            "mm" | "millimeters" => Ok(NumericSuffix::Mm),
70            "cm" | "centimeters" => Ok(NumericSuffix::Cm),
71            "m" | "meters" => Ok(NumericSuffix::M),
72            "inch" | "in" => Ok(NumericSuffix::Inch),
73            "ft" | "feet" => Ok(NumericSuffix::Ft),
74            "yd" | "yards" => Ok(NumericSuffix::Yd),
75            "deg" | "degrees" => Ok(NumericSuffix::Deg),
76            "rad" | "radians" => Ok(NumericSuffix::Rad),
77            "?" => Ok(NumericSuffix::Unknown),
78            _ => Err(CompilationIssue::err(SourceRange::default(), "invalid unit of measure")),
79        }
80    }
81}
82
83impl fmt::Display for NumericSuffix {
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        match self {
86            NumericSuffix::None => Ok(()),
87            NumericSuffix::Count => write!(f, "_"),
88            NumericSuffix::Unknown => write!(f, "_?"),
89            NumericSuffix::Length => write!(f, "Length"),
90            NumericSuffix::Angle => write!(f, "Angle"),
91            NumericSuffix::Mm => write!(f, "mm"),
92            NumericSuffix::Cm => write!(f, "cm"),
93            NumericSuffix::M => write!(f, "m"),
94            NumericSuffix::Inch => write!(f, "in"),
95            NumericSuffix::Ft => write!(f, "ft"),
96            NumericSuffix::Yd => write!(f, "yd"),
97            NumericSuffix::Deg => write!(f, "deg"),
98            NumericSuffix::Rad => write!(f, "rad"),
99        }
100    }
101}
102
103impl From<UnitLength> for NumericSuffix {
104    fn from(value: UnitLength) -> Self {
105        match value {
106            UnitLength::Millimeters => NumericSuffix::Mm,
107            UnitLength::Centimeters => NumericSuffix::Cm,
108            UnitLength::Meters => NumericSuffix::M,
109            UnitLength::Inches => NumericSuffix::Inch,
110            UnitLength::Feet => NumericSuffix::Ft,
111            UnitLength::Yards => NumericSuffix::Yd,
112        }
113    }
114}
115
116#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, ts_rs::TS)]
117pub struct NumericSuffixTypeConvertError;
118
119impl TryFrom<NumericType> for NumericSuffix {
120    type Error = NumericSuffixTypeConvertError;
121
122    fn try_from(value: NumericType) -> Result<Self, Self::Error> {
123        match value {
124            NumericType::Known(UnitType::Count) => Ok(NumericSuffix::Count),
125            NumericType::Known(UnitType::Length(unit_length)) => Ok(NumericSuffix::from(unit_length)),
126            NumericType::Known(UnitType::GenericLength) => Ok(NumericSuffix::Length),
127            NumericType::Known(UnitType::Angle(UnitAngle::Degrees)) => Ok(NumericSuffix::Deg),
128            NumericType::Known(UnitType::Angle(UnitAngle::Radians)) => Ok(NumericSuffix::Rad),
129            NumericType::Known(UnitType::GenericAngle) => Ok(NumericSuffix::Angle),
130            NumericType::Default { .. } => Ok(NumericSuffix::None),
131            NumericType::Unknown => Ok(NumericSuffix::Unknown),
132            NumericType::Any => Err(NumericSuffixTypeConvertError),
133        }
134    }
135}