use std::ops::Div;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use super::{
constants, Density, DensityUnit, Measurement, PhysicalQuantity, UnitOfMeasure, Volume,
VolumeUnit,
};
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(C)]
pub enum MassUnit {
Kilograms,
Pounds,
}
impl UnitOfMeasure<f32> for MassUnit {
fn quantity() -> PhysicalQuantity {
PhysicalQuantity::Mass
}
fn si() -> Self {
Self::Kilograms
}
fn symbol(&self) -> &'static str {
match self {
Self::Kilograms => "kg",
Self::Pounds => "lb",
}
}
fn from_si(value: f32, to: &Self) -> f32 {
match to {
Self::Kilograms => value,
Self::Pounds => value / constants::POUNDS_IN_KILOGRAMS,
}
}
fn to_si(&self, value: &f32) -> f32 {
match self {
Self::Kilograms => *value,
Self::Pounds => value * constants::POUNDS_IN_KILOGRAMS,
}
}
}
pub type Mass = Measurement<f32, MassUnit>;
impl Mass {
pub fn kg(value: f32) -> Self {
Mass {
value,
unit: MassUnit::Kilograms,
}
}
pub fn lb(value: f32) -> Self {
Mass {
value,
unit: MassUnit::Pounds,
}
}
}
impl Div<Density> for Mass {
type Output = Volume;
fn div(self, rhs: Density) -> Self::Output {
let unit = match rhs.unit {
DensityUnit::KilogramPerCubicMeter => VolumeUnit::CubicMeters,
DensityUnit::KilogramPerLiter => VolumeUnit::Liter,
};
Volume::from_si(self.to_si() / rhs.to_si(), unit)
}
}