Skip to main content

bo4e_core/enums/
unit_prefix.rs

1//! Unit prefix (Mengeneinheitenpraefix) enumeration.
2
3use serde::{Deserialize, Serialize};
4
5/// SI unit prefix.
6///
7/// Metric prefixes used with units of measurement.
8///
9/// German: Mengeneinheitenpraefix
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
11#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
12#[cfg_attr(feature = "json-schema", schemars(rename = "Mengeneinheitenpraefix"))]
13#[non_exhaustive]
14pub enum UnitPrefix {
15    /// Exa (10^18)
16    #[serde(rename = "EXA")]
17    Exa,
18
19    /// Peta (10^15)
20    #[serde(rename = "PETA")]
21    Peta,
22
23    /// Tera (10^12)
24    #[serde(rename = "TERA")]
25    Tera,
26
27    /// Giga (10^9)
28    #[serde(rename = "GIGA")]
29    Giga,
30
31    /// Mega (10^6)
32    #[serde(rename = "MEGA")]
33    Mega,
34
35    /// Kilo (10^3)
36    #[serde(rename = "KILO")]
37    Kilo,
38
39    /// Hecto (10^2)
40    #[serde(rename = "HEKTO")]
41    Hecto,
42
43    /// Deca (10^1)
44    #[serde(rename = "DEKA")]
45    Deca,
46
47    /// No prefix (10^0)
48    #[serde(rename = "OHNE")]
49    None,
50
51    /// Deci (10^-1)
52    #[serde(rename = "DEZI")]
53    Deci,
54
55    /// Centi (10^-2)
56    #[serde(rename = "ZENTI")]
57    Centi,
58
59    /// Milli (10^-3)
60    #[serde(rename = "MILLI")]
61    Milli,
62
63    /// Micro (10^-6)
64    #[serde(rename = "MIKRO")]
65    Micro,
66
67    /// Nano (10^-9)
68    #[serde(rename = "NANO")]
69    Nano,
70
71    /// Pico (10^-12)
72    #[serde(rename = "PIKO")]
73    Pico,
74
75    /// Femto (10^-15)
76    #[serde(rename = "FEMTO")]
77    Femto,
78
79    /// Atto (10^-18)
80    #[serde(rename = "ATTO")]
81    Atto,
82}
83
84impl UnitPrefix {
85    /// Returns the German name.
86    pub fn german_name(&self) -> &'static str {
87        match self {
88            Self::Exa => "Exa",
89            Self::Peta => "Peta",
90            Self::Tera => "Tera",
91            Self::Giga => "Giga",
92            Self::Mega => "Mega",
93            Self::Kilo => "Kilo",
94            Self::Hecto => "Hekto",
95            Self::Deca => "Deka",
96            Self::None => "Ohne",
97            Self::Deci => "Dezi",
98            Self::Centi => "Zenti",
99            Self::Milli => "Milli",
100            Self::Micro => "Mikro",
101            Self::Nano => "Nano",
102            Self::Pico => "Piko",
103            Self::Femto => "Femto",
104            Self::Atto => "Atto",
105        }
106    }
107
108    /// Returns the power of 10 for this prefix.
109    pub fn exponent(&self) -> i32 {
110        match self {
111            Self::Exa => 18,
112            Self::Peta => 15,
113            Self::Tera => 12,
114            Self::Giga => 9,
115            Self::Mega => 6,
116            Self::Kilo => 3,
117            Self::Hecto => 2,
118            Self::Deca => 1,
119            Self::None => 0,
120            Self::Deci => -1,
121            Self::Centi => -2,
122            Self::Milli => -3,
123            Self::Micro => -6,
124            Self::Nano => -9,
125            Self::Pico => -12,
126            Self::Femto => -15,
127            Self::Atto => -18,
128        }
129    }
130}
131
132#[cfg(test)]
133mod tests {
134    use super::*;
135
136    #[test]
137    fn test_serialize() {
138        assert_eq!(
139            serde_json::to_string(&UnitPrefix::Kilo).unwrap(),
140            r#""KILO""#
141        );
142        assert_eq!(
143            serde_json::to_string(&UnitPrefix::Mega).unwrap(),
144            r#""MEGA""#
145        );
146    }
147
148    #[test]
149    fn test_roundtrip() {
150        for prefix in [
151            UnitPrefix::Exa,
152            UnitPrefix::Kilo,
153            UnitPrefix::None,
154            UnitPrefix::Milli,
155            UnitPrefix::Nano,
156        ] {
157            let json = serde_json::to_string(&prefix).unwrap();
158            let parsed: UnitPrefix = serde_json::from_str(&json).unwrap();
159            assert_eq!(prefix, parsed);
160        }
161    }
162
163    #[test]
164    fn test_exponent() {
165        assert_eq!(UnitPrefix::Kilo.exponent(), 3);
166        assert_eq!(UnitPrefix::Mega.exponent(), 6);
167        assert_eq!(UnitPrefix::Milli.exponent(), -3);
168        assert_eq!(UnitPrefix::None.exponent(), 0);
169    }
170}