1use crate::{Quantity, Unit};
46use qtty_derive::Unit;
47
48pub use crate::dimension::Volume;
50
51pub trait VolumeUnit: Unit<Dim = Volume> {}
53impl<T: Unit<Dim = Volume>> VolumeUnit for T {}
54
55#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
61#[unit(symbol = "m³", dimension = Volume, ratio = 1.0)]
62pub struct CubicMeter;
63pub type CubicMeters = Quantity<CubicMeter>;
65
66#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
68#[unit(symbol = "km³", dimension = Volume, ratio = 1e9)]
69pub struct CubicKilometer;
70pub type CubicKilometers = Quantity<CubicKilometer>;
72
73#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
75#[unit(symbol = "cm³", dimension = Volume, ratio = 1e-6)]
76pub struct CubicCentimeter;
77pub type CubicCentimeters = Quantity<CubicCentimeter>;
79
80#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
82#[unit(symbol = "mm³", dimension = Volume, ratio = 1e-9)]
83pub struct CubicMillimeter;
84pub type CubicMillimeters = Quantity<CubicMillimeter>;
86
87#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
93#[unit(symbol = "L", dimension = Volume, ratio = 1e-3)]
94pub struct Liter;
95pub type Liters = Quantity<Liter>;
97
98#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
100#[unit(symbol = "mL", dimension = Volume, ratio = 1e-6)]
101pub struct Milliliter;
102pub type Milliliters = Quantity<Milliliter>;
104
105#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
107#[unit(symbol = "µL", dimension = Volume, ratio = 1e-9)]
108pub struct Microliter;
109pub type Microliters = Quantity<Microliter>;
111
112#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
114#[unit(symbol = "cL", dimension = Volume, ratio = 1e-5)]
115pub struct Centiliter;
116pub type Centiliters = Quantity<Centiliter>;
118
119#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
121#[unit(symbol = "dL", dimension = Volume, ratio = 1e-4)]
122pub struct Deciliter;
123pub type Deciliters = Quantity<Deciliter>;
125
126#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
132#[unit(symbol = "in³", dimension = Volume, ratio = 1.638_706_4e-5)]
133pub struct CubicInch;
134pub type CubicInches = Quantity<CubicInch>;
136
137#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
139#[unit(symbol = "ft³", dimension = Volume, ratio = 0.028_316_846_592)]
140pub struct CubicFoot;
141pub type CubicFeet = Quantity<CubicFoot>;
143
144#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
146#[unit(symbol = "gal", dimension = Volume, ratio = 0.003_785_411_784)]
147pub struct UsGallon;
148pub type UsGallons = Quantity<UsGallon>;
150
151#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Unit)]
153#[unit(symbol = "fl oz", dimension = Volume, ratio = 2.957_352_956_25e-5)]
154pub struct UsFluidOunce;
155pub type UsFluidOunces = Quantity<UsFluidOunce>;
157
158#[cfg(test)]
159mod tests {
160 use super::*;
161 use approx::assert_abs_diff_eq;
162
163 #[test]
164 fn liter_to_cubic_meter() {
165 let l = Liters::new(1.0);
166 let m: CubicMeters = l.to();
167 assert_abs_diff_eq!(m.value(), 0.001, epsilon = 1e-15);
168 }
169
170 #[test]
171 fn milliliter_to_liter() {
172 let ml = Milliliters::new(1000.0);
173 let l: Liters = ml.to();
174 assert_abs_diff_eq!(l.value(), 1.0, epsilon = 1e-12);
175 }
176
177 #[test]
178 fn cubic_cm_to_ml() {
179 let cc = CubicCentimeters::new(1.0);
180 let ml: Milliliters = cc.to();
181 assert_abs_diff_eq!(ml.value(), 1.0, epsilon = 1e-12);
182 }
183
184 #[test]
185 fn us_gallon_to_liter() {
186 let g = UsGallons::new(1.0);
187 let l: Liters = g.to();
188 assert_abs_diff_eq!(l.value(), 3.785_411_784, epsilon = 1e-6);
189 }
190
191 #[test]
192 fn cubic_foot_to_liter() {
193 let cf = CubicFeet::new(1.0);
194 let l: Liters = cf.to();
195 assert_abs_diff_eq!(l.value(), 28.316_846_592, epsilon = 1e-6);
196 }
197
198 #[test]
199 fn length_times_area_to_volume() {
200 use crate::area::{SquareMeter, SquareMeters};
201 use crate::length::{Meter, Meters};
202 use crate::Prod;
203
204 let side = Meters::new(3.0);
205 let face: SquareMeters = (side * side).to();
206 let vol_prod: Quantity<Prod<SquareMeter, Meter>> = face * side;
207 let vol: CubicMeters = vol_prod.to();
208 assert_abs_diff_eq!(vol.value(), 27.0, epsilon = 1e-12);
209 }
210
211 #[test]
212 fn cubic_km_to_liter() {
213 let ckm = CubicKilometers::new(1.0);
214 let l: Liters = ckm.to();
215 assert_abs_diff_eq!(l.value(), 1e12, epsilon = 1e3);
216 }
217
218 #[test]
219 fn cubic_mm_to_cubic_cm() {
220 let mm3 = CubicMillimeters::new(1000.0);
221 let cm3: CubicCentimeters = mm3.to();
222 assert_abs_diff_eq!(cm3.value(), 1.0, epsilon = 1e-12);
223 }
224
225 #[test]
226 fn microliter_to_milliliter() {
227 let ul = Microliters::new(1000.0);
228 let ml: Milliliters = ul.to();
229 assert_abs_diff_eq!(ml.value(), 1.0, epsilon = 1e-12);
230 }
231
232 #[test]
233 fn centiliter_to_liter() {
234 let cl = Centiliters::new(100.0);
235 let l: Liters = cl.to();
236 assert_abs_diff_eq!(l.value(), 1.0, epsilon = 1e-12);
237 }
238
239 #[test]
240 fn deciliter_to_liter() {
241 let dl = Deciliters::new(10.0);
242 let l: Liters = dl.to();
243 assert_abs_diff_eq!(l.value(), 1.0, epsilon = 1e-12);
244 }
245
246 #[test]
247 fn cubic_inch_to_cubic_cm() {
248 let cin = CubicInches::new(1.0);
249 let cc: CubicCentimeters = cin.to();
250 assert_abs_diff_eq!(cc.value(), 16.387_064, epsilon = 1e-4);
252 }
253
254 #[test]
255 fn us_fluid_ounce_to_milliliter() {
256 let floz = UsFluidOunces::new(1.0);
257 let ml: Milliliters = floz.to();
258 assert_abs_diff_eq!(ml.value(), 29.573_529_562_5, epsilon = 1e-6);
260 }
261
262 #[test]
263 fn symbols_are_correct() {
264 assert_eq!(CubicMeter::SYMBOL, "m³");
265 assert_eq!(Liter::SYMBOL, "L");
266 assert_eq!(Milliliter::SYMBOL, "mL");
267 assert_eq!(UsGallon::SYMBOL, "gal");
268 }
269}