use crate::{Quantity, Unit};
use qtty_derive::Unit;
pub use crate::dimension::Density;
pub trait DensityUnit: Unit<Dim = Density> {}
impl<T: Unit<Dim = Density>> DensityUnit for T {}
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "kg/m³", dimension = Density, ratio = 1.0)]
pub struct KilogramPerCubicMeter;
pub type KgM3 = KilogramPerCubicMeter;
pub type KilogramsPerCubicMeter = Quantity<KgM3>;
pub const KILOGRAM_PER_CUBIC_METER: KilogramsPerCubicMeter = KilogramsPerCubicMeter::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "g/cm³", dimension = Density, ratio = 1_000.0)]
pub struct GramPerCubicCentimeter;
pub type GCm3 = GramPerCubicCentimeter;
pub type GramsPerCubicCentimeter = Quantity<GCm3>;
pub const GRAM_PER_CUBIC_CENTIMETER: GramsPerCubicCentimeter = GramsPerCubicCentimeter::new(1.0);
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "g/mL", dimension = Density, ratio = 1_000.0)]
pub struct GramPerMilliliter;
pub type GmL = GramPerMilliliter;
pub type GramsPerMilliliter = Quantity<GmL>;
pub const GRAM_PER_MILLILITER: GramsPerMilliliter = GramsPerMilliliter::new(1.0);
#[cfg(feature = "customary")]
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
#[unit(symbol = "lb/ft³", dimension = Density, ratio = 16.018_463_373)]
pub struct PoundPerCubicFoot;
#[cfg(feature = "customary")]
pub type LbFt3 = PoundPerCubicFoot;
#[cfg(feature = "customary")]
pub type PoundsPerCubicFoot = Quantity<LbFt3>;
#[cfg(feature = "customary")]
pub const POUND_PER_CUBIC_FOOT: PoundsPerCubicFoot = PoundsPerCubicFoot::new(1.0);
#[macro_export]
#[doc(hidden)]
macro_rules! density_units {
($cb:path) => {
$cb!(
KilogramPerCubicMeter,
GramPerCubicCentimeter,
GramPerMilliliter
);
};
}
#[cfg(feature = "customary")]
#[macro_export]
#[doc(hidden)]
macro_rules! density_customary_units {
($cb:path) => {
$cb!(PoundPerCubicFoot);
};
}
density_units!(crate::impl_unit_from_conversions);
#[cfg(feature = "cross-unit-ops")]
density_units!(crate::impl_unit_cross_unit_ops);
#[cfg(feature = "customary")]
crate::impl_unit_from_conversions_between!(
KilogramPerCubicMeter, GramPerCubicCentimeter, GramPerMilliliter;
PoundPerCubicFoot
);
#[cfg(all(feature = "customary", feature = "cross-unit-ops"))]
crate::impl_unit_cross_unit_ops_between!(
KilogramPerCubicMeter, GramPerCubicCentimeter, GramPerMilliliter;
PoundPerCubicFoot
);
#[cfg(test)]
density_units!(crate::assert_units_are_builtin);
#[cfg(all(test, feature = "std"))]
mod tests {
use super::*;
use approx::assert_abs_diff_eq;
#[test]
fn gcc_to_kgm3() {
let gcc = GramsPerCubicCentimeter::new(1.0);
let kgm3: KilogramsPerCubicMeter = gcc.to();
assert_abs_diff_eq!(kgm3.value(), 1_000.0, epsilon = 1e-9);
}
#[test]
fn gml_equals_gcc() {
let gml = GramsPerMilliliter::new(2.5);
let gcc: GramsPerCubicCentimeter = gml.to();
assert_abs_diff_eq!(gcc.value(), 2.5, epsilon = 1e-12);
}
#[test]
fn water_density_at_4c() {
let kgm3 = KilogramsPerCubicMeter::new(1_000.0);
let gcc: GramsPerCubicCentimeter = kgm3.to();
assert_abs_diff_eq!(gcc.value(), 1.0, epsilon = 1e-12);
}
#[test]
#[cfg(feature = "customary")]
fn lbft3_to_kgm3() {
let lbft3 = PoundsPerCubicFoot::new(1.0);
let kgm3: KilogramsPerCubicMeter = lbft3.to();
assert_abs_diff_eq!(kgm3.value(), 16.018_463_373, epsilon = 1e-6);
}
}