danwi 0.4.2

Zero-cost dimensional analysis library with SI units, compile-time checking, and no_std support
Documentation
use super::{Quantity, fmt::UnitDisplay};
use crate::{
    dimension::{Dimensionless, Dimensions},
    scalar::Scalar,
    unit::{Unit, UnitDef},
};
use core::marker::PhantomData;

impl<S: Scalar, D: Dimensions> From<S> for Quantity<S, D> {
    /// Wraps a raw scalar already expressed in the SI base unit; equivalent
    /// to [`Quantity::from_base`].
    #[inline(always)]
    fn from(value: S) -> Self {
        Self::from_base(value)
    }
}

// A dimensionless quantity (e.g. the ratio of two voltages) converts back
// into its bare scalar.

#[cfg(feature = "f32")]
impl From<Quantity<f32, Dimensionless>> for f32 {
    #[inline(always)]
    fn from(q: Quantity<f32, Dimensionless>) -> Self {
        q.value
    }
}

#[cfg(feature = "f64")]
impl From<Quantity<f64, Dimensionless>> for f64 {
    #[inline(always)]
    fn from(q: Quantity<f64, Dimensionless>) -> Self {
        q.value
    }
}

#[cfg(feature = "f32")]
impl<D: Dimensions> Quantity<f32, D> {
    /// Construct from a raw base-unit scalar in a `const` context.
    #[inline(always)]
    pub const fn from_f32(value: f32) -> Self {
        Self::from_base(value)
    }

    /// Construct from a value expressed in the given unit.
    ///
    /// Equivalent to `value * unit`, but usable in `const` contexts.
    #[inline(always)]
    pub const fn new<M: UnitDef<Dim = D>>(value: f32, _unit: Unit<M>) -> Self {
        Self::from_base(crate::scalar::to_base_f32(
            value,
            M::SCALE_NUM,
            M::SCALE_DEN,
            M::OFFSET_NUM,
            M::OFFSET_DEN,
        ))
    }

    /// Extract the value expressed in the given unit.
    ///
    /// All arithmetic happens at the unit's const scale factor, so with
    /// const-known inputs this folds away entirely at compile time.
    #[inline(always)]
    pub const fn to<M: UnitDef<Dim = D>>(self, _unit: Unit<M>) -> f32 {
        crate::scalar::from_base_f32(
            self.value,
            M::SCALE_NUM,
            M::SCALE_DEN,
            M::OFFSET_NUM,
            M::OFFSET_DEN,
        )
    }

    /// Wrap the quantity for formatting in the given unit.
    ///
    /// Calling `display_as` does no work; it only packages the value and
    /// the unit for a later `Display` call.
    #[inline(always)]
    pub const fn display_as<M: UnitDef<Dim = D>>(self, _unit: Unit<M>) -> UnitDisplay<f32, M> {
        UnitDisplay {
            value: self.value,
            _phantom: PhantomData,
        }
    }
}

#[cfg(feature = "f64")]
impl<D: Dimensions> Quantity<f64, D> {
    /// Construct from a raw base-unit scalar in a `const` context.
    #[inline(always)]
    pub const fn from_f64(value: f64) -> Self {
        Self::from_base(value)
    }

    /// Construct from a value expressed in the given unit.
    ///
    /// Equivalent to `value * unit`, but usable in `const` contexts.
    #[inline(always)]
    pub const fn new<M: UnitDef<Dim = D>>(value: f64, _unit: Unit<M>) -> Self {
        Self::from_base(crate::scalar::to_base_f64(
            value,
            M::SCALE_NUM,
            M::SCALE_DEN,
            M::OFFSET_NUM,
            M::OFFSET_DEN,
        ))
    }

    /// Extract the value expressed in the given unit.
    ///
    /// All arithmetic happens at the unit's const scale factor, so with
    /// const-known inputs this folds away entirely at compile time.
    #[inline(always)]
    pub const fn to<M: UnitDef<Dim = D>>(self, _unit: Unit<M>) -> f64 {
        crate::scalar::from_base_f64(
            self.value,
            M::SCALE_NUM,
            M::SCALE_DEN,
            M::OFFSET_NUM,
            M::OFFSET_DEN,
        )
    }

    /// Wrap the quantity for formatting in the given unit.
    ///
    /// Calling `display_as` does no work; it only packages the value and
    /// the unit for a later `Display` call.
    #[inline(always)]
    pub const fn display_as<M: UnitDef<Dim = D>>(self, _unit: Unit<M>) -> UnitDisplay<f64, M> {
        UnitDisplay {
            value: self.value,
            _phantom: PhantomData,
        }
    }
}