1use crate::{Quantity, Unit};
28use qtty_derive::Unit;
29
30pub use crate::dimension::Volume;
32
33pub trait VolumeUnit: Unit<Dim = Volume> {}
35impl<T: Unit<Dim = Volume>> VolumeUnit for T {}
36
37#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
43#[unit(symbol = "m³", dimension = Volume, ratio = 1.0)]
44pub struct CubicMeter;
45pub type CubicMeters = Quantity<CubicMeter>;
47
48#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
50#[unit(symbol = "km³", dimension = Volume, ratio = 1e9)]
51pub struct CubicKilometer;
52pub type CubicKilometers = Quantity<CubicKilometer>;
54
55#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
57#[unit(symbol = "cm³", dimension = Volume, ratio = 1e-6)]
58pub struct CubicCentimeter;
59pub type CubicCentimeters = Quantity<CubicCentimeter>;
61
62#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
64#[unit(symbol = "mm³", dimension = Volume, ratio = 1e-9)]
65pub struct CubicMillimeter;
66pub type CubicMillimeters = Quantity<CubicMillimeter>;
68
69#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
75#[unit(symbol = "L", dimension = Volume, ratio = 1e-3)]
76pub struct Liter;
77pub type Liters = Quantity<Liter>;
79
80#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
82#[unit(symbol = "mL", dimension = Volume, ratio = 1e-6)]
83pub struct Milliliter;
84pub type Milliliters = Quantity<Milliliter>;
86
87#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
89#[unit(symbol = "µL", dimension = Volume, ratio = 1e-9)]
90pub struct Microliter;
91pub type Microliters = Quantity<Microliter>;
93
94#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
96#[unit(symbol = "cL", dimension = Volume, ratio = 1e-5)]
97pub struct Centiliter;
98pub type Centiliters = Quantity<Centiliter>;
100
101#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
103#[unit(symbol = "dL", dimension = Volume, ratio = 1e-4)]
104pub struct Deciliter;
105pub type Deciliters = Quantity<Deciliter>;
107
108#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
114#[unit(symbol = "in³", dimension = Volume, ratio = 1.638_706_4e-5)]
115pub struct CubicInch;
116pub type CubicInches = Quantity<CubicInch>;
118
119#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
121#[unit(symbol = "ft³", dimension = Volume, ratio = 0.028_316_846_592)]
122pub struct CubicFoot;
123pub type CubicFeet = Quantity<CubicFoot>;
125
126#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
128#[unit(symbol = "gal", dimension = Volume, ratio = 0.003_785_411_784)]
129pub struct UsGallon;
130pub type UsGallons = Quantity<UsGallon>;
132
133#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
135#[unit(symbol = "fl oz", dimension = Volume, ratio = 2.957_352_956_25e-5)]
136pub struct UsFluidOunce;
137pub type UsFluidOunces = Quantity<UsFluidOunce>;
139
140#[cfg(test)]
141mod tests {
142 use super::*;
143 use approx::assert_abs_diff_eq;
144
145 #[test]
146 fn liter_to_cubic_meter() {
147 let l = Liters::new(1.0);
148 let m: CubicMeters = l.to();
149 assert_abs_diff_eq!(m.value(), 0.001, epsilon = 1e-15);
150 }
151
152 #[test]
153 fn milliliter_to_liter() {
154 let ml = Milliliters::new(1000.0);
155 let l: Liters = ml.to();
156 assert_abs_diff_eq!(l.value(), 1.0, epsilon = 1e-12);
157 }
158
159 #[test]
160 fn cubic_cm_to_ml() {
161 let cc = CubicCentimeters::new(1.0);
162 let ml: Milliliters = cc.to();
163 assert_abs_diff_eq!(ml.value(), 1.0, epsilon = 1e-12);
164 }
165
166 #[test]
167 fn us_gallon_to_liter() {
168 let g = UsGallons::new(1.0);
169 let l: Liters = g.to();
170 assert_abs_diff_eq!(l.value(), 3.785_411_784, epsilon = 1e-6);
171 }
172
173 #[test]
174 fn cubic_foot_to_liter() {
175 let cf = CubicFeet::new(1.0);
176 let l: Liters = cf.to();
177 assert_abs_diff_eq!(l.value(), 28.316_846_592, epsilon = 1e-6);
178 }
179
180 #[test]
181 fn length_times_area_to_volume() {
182 use crate::area::{SquareMeter, SquareMeters};
183 use crate::length::{Meter, Meters};
184 use crate::Prod;
185
186 let side = Meters::new(3.0);
187 let face: SquareMeters = (side * side).to();
188 let vol_prod: Quantity<Prod<SquareMeter, Meter>> = face * side;
189 let vol: CubicMeters = vol_prod.to();
190 assert_abs_diff_eq!(vol.value(), 27.0, epsilon = 1e-12);
191 }
192
193 #[test]
194 fn cubic_km_to_liter() {
195 let ckm = CubicKilometers::new(1.0);
196 let l: Liters = ckm.to();
197 assert_abs_diff_eq!(l.value(), 1e12, epsilon = 1e3);
198 }
199}