diff --git a/src/quantity.rs b/src/quantity.rs index 93ab3200..afe3849a 100644 --- a/src/quantity.rs +++ b/src/quantity.rs @@ -284,6 +284,46 @@ macro_rules! quantity { $description } + /// Unit enum. + #[allow(non_camel_case_types)] + #[non_exhaustive] + #[derive(Debug, Clone, Copy)] + pub enum Units { + $(#[doc=$plural] $unit($unit),)+ + } + + impl Units { + /// Unit abbreviation. + pub fn abbreviation(&self) -> &'static str { + match self { + $(Units::$unit(_) => <$unit as super::Unit>::abbreviation(),)+ + } + } + + /// Unit singular description. + pub fn singular(&self) -> &'static str { + match self { + $(Units::$unit(_) => <$unit as super::Unit>::singular(),)+ + } + } + + /// Unit plural description. + pub fn plural(&self) -> &'static str { + match self { + $(Units::$unit(_) => <$unit as super::Unit>::plural(),)+ + } + } + } + + static ALL_UNITS: &[Units] = &[ + $(Units::$unit($unit),)+ + ]; + + /// Iterate over all defined units for this quantity. + pub fn units() -> impl Iterator { + ALL_UNITS.iter().copied() + } + impl $quantity where U: super::Units + ?Sized, diff --git a/src/tests/quantity.rs b/src/tests/quantity.rs index 7ccc6565..e089b667 100644 --- a/src/tests/quantity.rs +++ b/src/tests/quantity.rs @@ -182,6 +182,19 @@ storage_types! { a == b && a == c } } + + #[test] + fn test_units_iterator() { + let mut units_iter = crate::si::volume::units(); + + // Specifically check the first few units. Doubles as a test of abbreviation() and others + assert_eq!("Ym³", units_iter.next().unwrap().abbreviation()); + assert_eq!("cubic zettameter", units_iter.next().unwrap().singular()); + assert_eq!("cubic exameters", units_iter.next().unwrap().plural()); + + // And there should be 63 remaining units. + assert_eq!(63, units_iter.count()); + } } #[cfg(feature = "std")]