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