ifc_lite_core/project_units/
measure.rs1#[derive(Clone, Copy, Debug, PartialEq, Eq)]
18pub enum MeasureUnit {
19 Typed {
23 unit_type: &'static str,
25 default_symbol: &'static str,
28 },
29 Monetary,
31 Dimensionless,
33}
34
35pub fn measure_unit(measure_type: &str) -> Option<MeasureUnit> {
39 let up = measure_type.trim().to_ascii_uppercase();
42 let key = up.strip_prefix("IFC").unwrap_or(&up);
43 Some(match key {
44 "LENGTHMEASURE" | "POSITIVELENGTHMEASURE" | "NONNEGATIVELENGTHMEASURE" => {
46 MeasureUnit::Typed { unit_type: "LENGTHUNIT", default_symbol: "m" }
47 }
48 "AREAMEASURE" => MeasureUnit::Typed { unit_type: "AREAUNIT", default_symbol: "m\u{00B2}" },
49 "VOLUMEMEASURE" => {
50 MeasureUnit::Typed { unit_type: "VOLUMEUNIT", default_symbol: "m\u{00B3}" }
51 }
52 "MASSMEASURE" => MeasureUnit::Typed { unit_type: "MASSUNIT", default_symbol: "kg" },
53 "TIMEMEASURE" => MeasureUnit::Typed { unit_type: "TIMEUNIT", default_symbol: "s" },
54 "PLANEANGLEMEASURE" | "POSITIVEPLANEANGLEMEASURE" => {
55 MeasureUnit::Typed { unit_type: "PLANEANGLEUNIT", default_symbol: "rad" }
56 }
57 "SOLIDANGLEMEASURE" => {
58 MeasureUnit::Typed { unit_type: "SOLIDANGLEUNIT", default_symbol: "sr" }
59 }
60 "THERMODYNAMICTEMPERATUREMEASURE" => MeasureUnit::Typed {
61 unit_type: "THERMODYNAMICTEMPERATUREUNIT",
62 default_symbol: "K",
63 },
64
65 "ELECTRICCURRENTMEASURE" => {
67 MeasureUnit::Typed { unit_type: "ELECTRICCURRENTUNIT", default_symbol: "A" }
68 }
69 "ELECTRICVOLTAGEMEASURE" => {
70 MeasureUnit::Typed { unit_type: "ELECTRICVOLTAGEUNIT", default_symbol: "V" }
71 }
72 "ELECTRICRESISTANCEMEASURE" => MeasureUnit::Typed {
73 unit_type: "ELECTRICRESISTANCEUNIT",
74 default_symbol: "\u{03A9}",
75 },
76 "ELECTRICCAPACITANCEMEASURE" => {
77 MeasureUnit::Typed { unit_type: "ELECTRICCAPACITANCEUNIT", default_symbol: "F" }
78 }
79 "ELECTRICCHARGEMEASURE" => {
80 MeasureUnit::Typed { unit_type: "ELECTRICCHARGEUNIT", default_symbol: "C" }
81 }
82 "ELECTRICCONDUCTANCEMEASURE" => {
83 MeasureUnit::Typed { unit_type: "ELECTRICCONDUCTANCEUNIT", default_symbol: "S" }
84 }
85 "POWERMEASURE" => MeasureUnit::Typed { unit_type: "POWERUNIT", default_symbol: "W" },
86 "ENERGYMEASURE" => MeasureUnit::Typed { unit_type: "ENERGYUNIT", default_symbol: "J" },
87 "FORCEMEASURE" => MeasureUnit::Typed { unit_type: "FORCEUNIT", default_symbol: "N" },
88 "PRESSUREMEASURE" => {
89 MeasureUnit::Typed { unit_type: "PRESSUREUNIT", default_symbol: "Pa" }
90 }
91 "FREQUENCYMEASURE" => {
92 MeasureUnit::Typed { unit_type: "FREQUENCYUNIT", default_symbol: "Hz" }
93 }
94 "INDUCTANCEMEASURE" => {
95 MeasureUnit::Typed { unit_type: "INDUCTANCEUNIT", default_symbol: "H" }
96 }
97 "ILLUMINANCEMEASURE" => {
98 MeasureUnit::Typed { unit_type: "ILLUMINANCEUNIT", default_symbol: "lx" }
99 }
100 "LUMINOUSFLUXMEASURE" => {
101 MeasureUnit::Typed { unit_type: "LUMINOUSFLUXUNIT", default_symbol: "lm" }
102 }
103 "LUMINOUSINTENSITYMEASURE" => {
104 MeasureUnit::Typed { unit_type: "LUMINOUSINTENSITYUNIT", default_symbol: "cd" }
105 }
106 "MAGNETICFLUXMEASURE" => {
107 MeasureUnit::Typed { unit_type: "MAGNETICFLUXUNIT", default_symbol: "Wb" }
108 }
109 "MAGNETICFLUXDENSITYMEASURE" => {
110 MeasureUnit::Typed { unit_type: "MAGNETICFLUXDENSITYUNIT", default_symbol: "T" }
111 }
112 "AMOUNTOFSUBSTANCEMEASURE" => {
113 MeasureUnit::Typed { unit_type: "AMOUNTOFSUBSTANCEUNIT", default_symbol: "mol" }
114 }
115 "ABSORBEDDOSEMEASURE" => {
116 MeasureUnit::Typed { unit_type: "ABSORBEDDOSEUNIT", default_symbol: "Gy" }
117 }
118 "DOSEEQUIVALENTMEASURE" => {
119 MeasureUnit::Typed { unit_type: "DOSEEQUIVALENTUNIT", default_symbol: "Sv" }
120 }
121 "RADIOACTIVITYMEASURE" => {
122 MeasureUnit::Typed { unit_type: "RADIOACTIVITYUNIT", default_symbol: "Bq" }
123 }
124
125 "VOLUMETRICFLOWRATEMEASURE" => MeasureUnit::Typed {
127 unit_type: "VOLUMETRICFLOWRATEUNIT",
128 default_symbol: "m\u{00B3}/s",
129 },
130 "MASSFLOWRATEMEASURE" => {
131 MeasureUnit::Typed { unit_type: "MASSFLOWRATEUNIT", default_symbol: "kg/s" }
132 }
133 "MASSDENSITYMEASURE" => {
134 MeasureUnit::Typed { unit_type: "MASSDENSITYUNIT", default_symbol: "kg/m\u{00B3}" }
135 }
136 "MASSPERLENGTHMEASURE" => {
137 MeasureUnit::Typed { unit_type: "MASSPERLENGTHUNIT", default_symbol: "kg/m" }
138 }
139 "LINEARVELOCITYMEASURE" => {
140 MeasureUnit::Typed { unit_type: "LINEARVELOCITYUNIT", default_symbol: "m/s" }
141 }
142 "ACCELERATIONMEASURE" => {
143 MeasureUnit::Typed { unit_type: "ACCELERATIONUNIT", default_symbol: "m/s\u{00B2}" }
144 }
145 "ANGULARVELOCITYMEASURE" => {
146 MeasureUnit::Typed { unit_type: "ANGULARVELOCITYUNIT", default_symbol: "rad/s" }
147 }
148 "ROTATIONALFREQUENCYMEASURE" => {
149 MeasureUnit::Typed { unit_type: "ROTATIONALFREQUENCYUNIT", default_symbol: "1/s" }
150 }
151 "TORQUEMEASURE" => {
152 MeasureUnit::Typed { unit_type: "TORQUEUNIT", default_symbol: "N\u{00B7}m" }
153 }
154 "LINEARFORCEMEASURE" => {
155 MeasureUnit::Typed { unit_type: "LINEARFORCEUNIT", default_symbol: "N/m" }
156 }
157 "PLANARFORCEMEASURE" => {
158 MeasureUnit::Typed { unit_type: "PLANARFORCEUNIT", default_symbol: "N/m\u{00B2}" }
159 }
160 "LINEARSTIFFNESSMEASURE" => {
161 MeasureUnit::Typed { unit_type: "LINEARSTIFFNESSUNIT", default_symbol: "N/m" }
162 }
163 "ROTATIONALSTIFFNESSMEASURE" => MeasureUnit::Typed {
164 unit_type: "ROTATIONALSTIFFNESSUNIT",
165 default_symbol: "N\u{00B7}m/rad",
166 },
167 "MODULUSOFELASTICITYMEASURE" => {
168 MeasureUnit::Typed { unit_type: "MODULUSOFELASTICITYUNIT", default_symbol: "Pa" }
169 }
170 "SHEARMODULUSMEASURE" => {
171 MeasureUnit::Typed { unit_type: "SHEARMODULUSUNIT", default_symbol: "Pa" }
172 }
173 "THERMALTRANSMITTANCEMEASURE" => MeasureUnit::Typed {
174 unit_type: "THERMALTRANSMITTANCEUNIT",
175 default_symbol: "W/(m\u{00B2}\u{00B7}K)",
176 },
177 "THERMALCONDUCTIVITYMEASURE" => MeasureUnit::Typed {
178 unit_type: "THERMALCONDUCTANCEUNIT",
179 default_symbol: "W/(m\u{00B7}K)",
180 },
181 "THERMALRESISTANCEMEASURE" => MeasureUnit::Typed {
182 unit_type: "THERMALRESISTANCEUNIT",
183 default_symbol: "m\u{00B2}\u{00B7}K/W",
184 },
185 "THERMALADMITTANCEMEASURE" => MeasureUnit::Typed {
186 unit_type: "THERMALADMITTANCEUNIT",
187 default_symbol: "W/(m\u{00B2}\u{00B7}K)",
188 },
189 "THERMALEXPANSIONCOEFFICIENTMEASURE" => MeasureUnit::Typed {
190 unit_type: "THERMALEXPANSIONCOEFFICIENTUNIT",
191 default_symbol: "1/K",
192 },
193 "SPECIFICHEATCAPACITYMEASURE" => MeasureUnit::Typed {
194 unit_type: "SPECIFICHEATCAPACITYUNIT",
195 default_symbol: "J/(kg\u{00B7}K)",
196 },
197 "HEATFLUXDENSITYMEASURE" => {
198 MeasureUnit::Typed { unit_type: "HEATFLUXDENSITYUNIT", default_symbol: "W/m\u{00B2}" }
199 }
200 "HEATINGVALUEMEASURE" => {
201 MeasureUnit::Typed { unit_type: "HEATINGVALUEUNIT", default_symbol: "J/kg" }
202 }
203 "DYNAMICVISCOSITYMEASURE" => {
204 MeasureUnit::Typed { unit_type: "DYNAMICVISCOSITYUNIT", default_symbol: "Pa\u{00B7}s" }
205 }
206 "KINEMATICVISCOSITYMEASURE" => {
207 MeasureUnit::Typed { unit_type: "KINEMATICVISCOSITYUNIT", default_symbol: "m\u{00B2}/s" }
208 }
209 "MOMENTOFINERTIAMEASURE" => {
210 MeasureUnit::Typed { unit_type: "MOMENTOFINERTIAUNIT", default_symbol: "m\u{2074}" }
211 }
212 "SECTIONMODULUSMEASURE" => {
213 MeasureUnit::Typed { unit_type: "SECTIONMODULUSUNIT", default_symbol: "m\u{00B3}" }
214 }
215 "SECTIONALAREAINTEGRALMEASURE" => {
216 MeasureUnit::Typed { unit_type: "SECTIONAREAINTEGRALUNIT", default_symbol: "m\u{2075}" }
217 }
218 "WARPINGCONSTANTMEASURE" => {
219 MeasureUnit::Typed { unit_type: "WARPINGCONSTANTUNIT", default_symbol: "m\u{2076}" }
220 }
221 "WARPINGMOMENTMEASURE" => MeasureUnit::Typed {
222 unit_type: "WARPINGMOMENTUNIT",
223 default_symbol: "N\u{00B7}m\u{00B2}",
224 },
225 "LINEARMOMENTMEASURE" => {
226 MeasureUnit::Typed { unit_type: "LINEARMOMENTUNIT", default_symbol: "N\u{00B7}m/m" }
227 }
228 "AREADENSITYMEASURE" => {
229 MeasureUnit::Typed { unit_type: "AREADENSITYUNIT", default_symbol: "kg/m\u{00B2}" }
230 }
231 "CURVATUREMEASURE" => {
232 MeasureUnit::Typed { unit_type: "CURVATUREUNIT", default_symbol: "1/m" }
233 }
234 "MOLECULARWEIGHTMEASURE" => {
235 MeasureUnit::Typed { unit_type: "MOLECULARWEIGHTUNIT", default_symbol: "kg/mol" }
236 }
237 "IONCONCENTRATIONMEASURE" => {
238 MeasureUnit::Typed { unit_type: "IONCONCENTRATIONUNIT", default_symbol: "kg/m\u{00B3}" }
239 }
240 "MOISTUREDIFFUSIVITYMEASURE" => {
241 MeasureUnit::Typed { unit_type: "MOISTUREDIFFUSIVITYUNIT", default_symbol: "m\u{00B2}/s" }
242 }
243 "VAPORPERMEABILITYMEASURE" => MeasureUnit::Typed {
244 unit_type: "VAPORPERMEABILITYUNIT",
245 default_symbol: "kg/(s\u{00B7}m\u{00B7}Pa)",
246 },
247 "ISOTHERMALMOISTURECAPACITYMEASURE" => MeasureUnit::Typed {
248 unit_type: "ISOTHERMALMOISTURECAPACITYUNIT",
249 default_symbol: "m\u{00B3}/kg",
250 },
251 "TEMPERATUREGRADIENTMEASURE" => {
252 MeasureUnit::Typed { unit_type: "TEMPERATUREGRADIENTUNIT", default_symbol: "K/m" }
253 }
254 "TEMPERATURERATEOFCHANGEMEASURE" => MeasureUnit::Typed {
255 unit_type: "TEMPERATURERATEOFCHANGEUNIT",
256 default_symbol: "K/s",
257 },
258 "SOUNDPOWERMEASURE" => {
259 MeasureUnit::Typed { unit_type: "SOUNDPOWERUNIT", default_symbol: "W" }
260 }
261 "SOUNDPOWERLEVELMEASURE" => {
262 MeasureUnit::Typed { unit_type: "SOUNDPOWERLEVELUNIT", default_symbol: "dB" }
263 }
264 "SOUNDPRESSUREMEASURE" => {
265 MeasureUnit::Typed { unit_type: "SOUNDPRESSUREUNIT", default_symbol: "Pa" }
266 }
267 "SOUNDPRESSURELEVELMEASURE" => {
268 MeasureUnit::Typed { unit_type: "SOUNDPRESSURELEVELUNIT", default_symbol: "dB" }
269 }
270 "MODULUSOFSUBGRADEREACTIONMEASURE" => MeasureUnit::Typed {
271 unit_type: "MODULUSOFSUBGRADEREACTIONUNIT",
272 default_symbol: "N/m\u{00B3}",
273 },
274 "MODULUSOFLINEARSUBGRADEREACTIONMEASURE" => MeasureUnit::Typed {
275 unit_type: "MODULUSOFLINEARSUBGRADEREACTIONUNIT",
276 default_symbol: "N/m\u{00B2}",
277 },
278 "MODULUSOFROTATIONALSUBGRADEREACTIONMEASURE" => MeasureUnit::Typed {
279 unit_type: "MODULUSOFROTATIONALSUBGRADEREACTIONUNIT",
280 default_symbol: "N/rad",
281 },
282 "ROTATIONALMASSMEASURE" => {
283 MeasureUnit::Typed { unit_type: "ROTATIONALMASSUNIT", default_symbol: "kg\u{00B7}m\u{00B2}" }
284 }
285 "INTEGERCOUNTRATEMEASURE" => {
286 MeasureUnit::Typed { unit_type: "INTEGERCOUNTRATEUNIT", default_symbol: "1/s" }
287 }
288 "LUMINOUSINTENSITYDISTRIBUTIONMEASURE" => MeasureUnit::Typed {
289 unit_type: "LUMINOUSINTENSITYDISTRIBUTIONUNIT",
290 default_symbol: "cd/lm",
291 },
292
293 "MONETARYMEASURE" => MeasureUnit::Monetary,
295
296 "RATIOMEASURE" | "NORMALISEDRATIOMEASURE" | "POSITIVERATIOMEASURE" | "COUNTMEASURE"
298 | "NUMERICMEASURE" | "DESCRIPTIVEMEASURE" | "CONTEXTDEPENDENTMEASURE" | "PHMEASURE"
299 | "CURVEMEASURE" | "COMPOUNDPLANEANGLEMEASURE" | "DERIVEDMEASURE" | "MEASURE" => {
300 MeasureUnit::Dimensionless
301 }
302
303 _ => return None,
305 })
306}
307
308#[cfg(test)]
309mod tests {
310 use super::*;
311
312 #[test]
313 fn issue_1573_flow_rate_maps_to_derived_unit() {
314 assert_eq!(
315 measure_unit("IFCVOLUMETRICFLOWRATEMEASURE"),
316 Some(MeasureUnit::Typed {
317 unit_type: "VOLUMETRICFLOWRATEUNIT",
318 default_symbol: "m\u{00B3}/s",
319 })
320 );
321 }
322
323 #[test]
324 fn accepts_prefixed_or_bare_names_case_insensitively() {
325 let a = measure_unit("IfcAreaMeasure");
326 let b = measure_unit("AREAMEASURE");
327 assert_eq!(a, b);
328 assert_eq!(
329 a,
330 Some(MeasureUnit::Typed { unit_type: "AREAUNIT", default_symbol: "m\u{00B2}" })
331 );
332 }
333
334 #[test]
335 fn length_family_shares_length_unit() {
336 for m in ["IFCLENGTHMEASURE", "IFCPOSITIVELENGTHMEASURE", "IFCNONNEGATIVELENGTHMEASURE"] {
337 assert_eq!(
338 measure_unit(m),
339 Some(MeasureUnit::Typed { unit_type: "LENGTHUNIT", default_symbol: "m" })
340 );
341 }
342 }
343
344 #[test]
345 fn ratios_and_counts_are_dimensionless() {
346 for m in ["IFCRATIOMEASURE", "IFCCOUNTMEASURE", "IFCNORMALISEDRATIOMEASURE"] {
347 assert_eq!(measure_unit(m), Some(MeasureUnit::Dimensionless));
348 }
349 }
350
351 #[test]
352 fn non_measures_return_none() {
353 assert_eq!(measure_unit("IFCLABEL"), None);
354 assert_eq!(measure_unit("IFCBOOLEAN"), None);
355 assert_eq!(measure_unit("IFCIDENTIFIER"), None);
356 }
357
358 #[test]
359 fn monetary_is_flagged() {
360 assert_eq!(measure_unit("IFCMONETARYMEASURE"), Some(MeasureUnit::Monetary));
361 }
362}