From 559c3d2a147c9de2117071e283eaafcfd9f49381 Mon Sep 17 00:00:00 2001 From: Zachary Levy Date: Sun, 28 Jun 2026 18:14:27 -0700 Subject: [PATCH] Added micro liters and gallons --- src/quantity/volume.rs | 113 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 2 deletions(-) diff --git a/src/quantity/volume.rs b/src/quantity/volume.rs index 45bbb7a..6cf18c3 100644 --- a/src/quantity/volume.rs +++ b/src/quantity/volume.rs @@ -1,7 +1,11 @@ use crate::quantity::{Quantity, Value}; use generate_quantity::quantity_type; -use crate::quantity::MILLI; +use crate::quantity::{MICRO, MILLI}; + +const LITERS_PER_GALLON: f64 = 3_785_411_784.0 / 1_000_000_000.0; +const MILLI_LITERS_PER_GALLON: f64 = 3_785_411_784.0 / 1_000_000.0; +const MICRO_LITERS_PER_GALLON: f64 = 3_785_411_784.0 / 1_000.0; //----- Liters ---------------------------------- quantity_type! {Liters, "L"} @@ -12,6 +16,18 @@ impl Liters { let multiplier = V::from_u16(MILLI).unwrap(); MilliLiters(self.0 * multiplier) } + + #[inline] + pub fn to_micro_liters(self) -> MicroLiters { + let multiplier = V::from_u32(MICRO).unwrap(); + MicroLiters(self.0 * multiplier) + } + + #[inline] + pub fn to_gallons(self) -> Gallons { + let divisor = V::from_f64(LITERS_PER_GALLON).unwrap(); + Gallons(self.0 / divisor) + } } //----- Milliliters ---------------------------------- @@ -23,6 +39,64 @@ impl MilliLiters { let divisor = V::from_u16(MILLI).unwrap(); Liters(self.0 / divisor) } + + #[inline] + pub fn to_micro_liters(self) -> MicroLiters { + let multiplier = V::from_u16(MILLI).unwrap(); + MicroLiters(self.0 * multiplier) + } + + #[inline] + pub fn to_gallons(self) -> Gallons { + let divisor = V::from_f64(MILLI_LITERS_PER_GALLON).unwrap(); + Gallons(self.0 / divisor) + } +} + +//----- Microliters ---------------------------------- +quantity_type! {MicroLiters, "µL"} + +impl MicroLiters { + #[inline] + pub fn to_liters(self) -> Liters { + let divisor = V::from_u32(MICRO).unwrap(); + Liters(self.0 / divisor) + } + + #[inline] + pub fn to_milli_liters(self) -> MilliLiters { + let divisor = V::from_u16(MILLI).unwrap(); + MilliLiters(self.0 / divisor) + } + + #[inline] + pub fn to_gallons(self) -> Gallons { + let divisor = V::from_f64(MICRO_LITERS_PER_GALLON).unwrap(); + Gallons(self.0 / divisor) + } +} + +//----- Gallons ---------------------------------- +quantity_type! {Gallons, "gal"} + +impl Gallons { + #[inline] + pub fn to_liters(self) -> Liters { + let multiplier = V::from_f64(LITERS_PER_GALLON).unwrap(); + Liters(self.0 * multiplier) + } + + #[inline] + pub fn to_milli_liters(self) -> MilliLiters { + let multiplier = V::from_f64(MILLI_LITERS_PER_GALLON).unwrap(); + MilliLiters(self.0 * multiplier) + } + + #[inline] + pub fn to_micro_liters(self) -> MicroLiters { + let multiplier = V::from_f64(MICRO_LITERS_PER_GALLON).unwrap(); + MicroLiters(self.0 * multiplier) + } } // --------------------------------------------------------------------------------------------------------------------- @@ -31,13 +105,48 @@ impl MilliLiters { #[cfg(test)] mod tests { use super::*; + use float_cmp::assert_approx_eq; #[test] - fn convert_u32() { + fn convert_metric_u32() { let liters: Liters = 12.liters(); let milli_liters: MilliLiters = 12_000.milli_liters(); + let micro_liters: MicroLiters = 12_000_000.micro_liters(); assert_eq!(liters.0, milli_liters.to_liters().0); assert_eq!(milli_liters.0, liters.to_milli_liters().0); + + assert_eq!(liters.0, micro_liters.to_liters().0); + assert_eq!(micro_liters.0, liters.to_micro_liters().0); + + assert_eq!(milli_liters.0, micro_liters.to_milli_liters().0); + assert_eq!(micro_liters.0, milli_liters.to_micro_liters().0); + } + + #[test] + fn gallons_liters() { + let gallons: Gallons = 1.0.gallons(); + let liters: Liters = 3.785411784.liters(); + + assert_approx_eq!(f64, gallons.to_liters().0, liters.0); + assert_approx_eq!(f64, liters.to_gallons().0, gallons.0); + } + + #[test] + fn gallons_milli_liters() { + let gallons: Gallons = 1.0.gallons(); + let milli_liters: MilliLiters = 3_785.411784.milli_liters(); + + assert_approx_eq!(f64, gallons.to_milli_liters().0, milli_liters.0); + assert_approx_eq!(f64, milli_liters.to_gallons().0, gallons.0); + } + + #[test] + fn gallons_micro_liters() { + let gallons: Gallons = 1.0.gallons(); + let micro_liters: MicroLiters = 3_785_411.784.micro_liters(); + + assert_approx_eq!(f64, gallons.to_micro_liters().0, micro_liters.0); + assert_approx_eq!(f64, micro_liters.to_gallons().0, gallons.0); } }