diman_unit_system 0.4.0

Internal procedural macros for diman.
Documentation
macro_rules! make_prefix_enum {
    ($enum_name: ident, $(($variant_name: ident, $lowercase_name: ident, $name: literal, $short: literal, $factor: literal)),*) => {
        #[derive(Clone, Copy, PartialEq)]
        pub enum $enum_name {
            $(
                $variant_name,
            )*
        }

        impl $enum_name {
            pub fn name(self) -> &'static str {
                match self {
                    $(
                        Self::$variant_name => $name,
                    )*
                }
            }

            pub fn short(self) -> &'static str {
                match self {
                    $(
                        Self::$variant_name => $short,
                    )*
                }
            }

            pub fn factor(self) -> f64 {
                match self {
                    $(
                        Self::$variant_name => $factor,
                    )*
                }
            }
        }

        impl ::syn::parse::Parse for $enum_name {
            fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
                mod kws {
                    $(
                        syn::custom_keyword!($lowercase_name);
                    )*
                }
                let lookahead = input.lookahead1();
                $(
                    if lookahead.peek(kws::$lowercase_name) {
                        let _: kws::$lowercase_name = input.parse()?;
                        return Ok(Self::$variant_name);
                    }
                )*
                Err(lookahead.error())
            }
        }
    }
}

make_prefix_enum! {
    Prefix,
    (Exa, exa, "exa",  "E",  1e18),
    (Peta, peta, "peta",  "P",  1e15),
    (Tera, tera, "tera",  "T",  1e12),
    (Giga, giga, "giga",  "G",  1e9),
    (Mega, mega, "mega",  "M",  1e6),
    (Kilo, kilo, "kilo",  "k",  1e3),
    (Hecto, hecto, "hecto",  "h",  1e2),
    (Deca, deca, "deca",  "da",  1e1),
    (Deci, deci, "deci",  "d",  1e-1),
    (Centi, centi, "centi",  "c",  1e-2),
    (Milli, milli, "milli",  "m",  1e-3),
    (Micro, micro, "micro",  "μ",  1e-6),
    (Nano, nano, "nano",  "n",  1e-9),
    (Pico, pico, "pico",  "p",  1e-12),
    (Femto, femto, "femto",  "f",  1e-15),
    (Atto, atto, "atto",  "a",  1e-18)
}

pub struct MetricPrefixes {
    pub skip: Vec<Prefix>,
}

impl From<MetricPrefixes> for Vec<Prefix> {
    fn from(def: MetricPrefixes) -> Self {
        vec![
            Prefix::Exa,
            Prefix::Peta,
            Prefix::Tera,
            Prefix::Giga,
            Prefix::Mega,
            Prefix::Kilo,
            Prefix::Hecto,
            Prefix::Deca,
            Prefix::Deci,
            Prefix::Centi,
            Prefix::Milli,
            Prefix::Micro,
            Prefix::Nano,
            Prefix::Pico,
            Prefix::Femto,
            Prefix::Atto,
        ]
        .into_iter()
        .filter(|prefix| !def.skip.contains(prefix))
        .collect()
    }
}

pub struct ExplicitPrefixes(pub Vec<Prefix>);