danwi 0.4.2

Zero-cost dimensional analysis library with SI units, compile-time checking, and no_std support
Documentation
//! SI prefixes as generic marker wrappers.
//!
//! `Kilo<Volt>` is itself a [`UnitDef`] whose scale is the wrapped unit's
//! scale times 10³, reduced to lowest terms at compile time.

use super::{UnitDef, reduce_den, reduce_num};
use core::marker::PhantomData;

/// Marker for units that accept SI prefixes.
///
/// Implemented by the [`units!`](crate::units) macro for entries declared
/// with `prefixes: all`. Requires a zero-offset unit (a prefixed affine
/// unit like "millicelsius" has no coherent meaning).
pub trait Prefixable: UnitDef {}

macro_rules! define_prefixes {
    ($($(#[$meta:meta])* $prefix:ident, $symbol:literal, $num:literal / $den:literal;)*) => {
        $(
            $(#[$meta])*
            pub struct $prefix<U> {
                _phantom: PhantomData<U>,
            }

            impl<U: Prefixable> UnitDef for $prefix<U> {
                type Dim = U::Dim;

                const SCALE_NUM: i128 =
                    reduce_num(U::SCALE_NUM * $num, U::SCALE_DEN * $den);
                const SCALE_DEN: i128 =
                    reduce_den(U::SCALE_NUM * $num, U::SCALE_DEN * $den);
                const OFFSET_NUM: i128 = 0;
                const OFFSET_DEN: i128 = 1;

                const PREFIX: &'static str = $symbol;
                const SYMBOL: &'static str = U::SYMBOL;
            }
        )*
    };
}

define_prefixes! {
    /// 10³⁰
    Quetta, "Q", 1_000_000_000_000_000_000_000_000_000_000 / 1;
    /// 10²⁷
    Ronna, "R", 1_000_000_000_000_000_000_000_000_000 / 1;
    /// 10²⁴
    Yotta, "Y", 1_000_000_000_000_000_000_000_000 / 1;
    /// 10²¹
    Zetta, "Z", 1_000_000_000_000_000_000_000 / 1;
    /// 10¹⁸
    Exa, "E", 1_000_000_000_000_000_000 / 1;
    /// 10¹⁵
    Peta, "P", 1_000_000_000_000_000 / 1;
    /// 10¹²
    Tera, "T", 1_000_000_000_000 / 1;
    /// 10⁹
    Giga, "G", 1_000_000_000 / 1;
    /// 10⁶
    Mega, "M", 1_000_000 / 1;
    /// 10³
    Kilo, "k", 1_000 / 1;
    /// 10²
    Hecto, "h", 100 / 1;
    /// 10¹
    Deca, "da", 10 / 1;
    /// 10⁻¹
    Deci, "d", 1 / 10;
    /// 10⁻²
    Centi, "c", 1 / 100;
    /// 10⁻³
    Milli, "m", 1 / 1_000;
    /// 10⁻⁶
    Micro, "u", 1 / 1_000_000;
    /// 10⁻⁹
    Nano, "n", 1 / 1_000_000_000;
    /// 10⁻¹²
    Pico, "p", 1 / 1_000_000_000_000;
    /// 10⁻¹⁵
    Femto, "f", 1 / 1_000_000_000_000_000;
    /// 10⁻¹⁸
    Atto, "a", 1 / 1_000_000_000_000_000_000;
    /// 10⁻²¹
    Zepto, "z", 1 / 1_000_000_000_000_000_000_000;
    /// 10⁻²⁴
    Yocto, "y", 1 / 1_000_000_000_000_000_000_000_000;
    /// 10⁻²⁷
    Ronto, "r", 1 / 1_000_000_000_000_000_000_000_000_000;
    /// 10⁻³⁰
    Quecto, "q", 1 / 1_000_000_000_000_000_000_000_000_000_000;
}