use std::ops::Mul; trait Volume { /// Returns the volume in SI units (cubic metres). fn si(self) -> CubicMetre; } #[derive(Debug, PartialEq)] struct CubicMetre(f64); #[derive(Debug, PartialEq)] struct Litre(f64); impl Volume for Litre { fn si(self) -> CubicMetre { CubicMetre(self.0 * 10_f64.powf(-3.)) } } impl From for Litre { fn from(value: i32) -> Self { Self(value as f64) } } impl From for Litre { fn from(value: CubicMetre) -> Self { Self(value.0 * 10_f64.powf(3.)) } } impl Mul for Litre { type Output = Self; fn mul(self, rhs: f64) -> Self::Output { Self(self.0 * rhs) } } #[cfg(test)] mod tests { use crate::volume::{CubicMetre, Litre, Volume}; #[test] fn litre_to_cubic_metre() { assert_eq!(Litre(1000.).si(), CubicMetre(1.)) } #[test] fn cubic_metre_to_litre() { assert_eq!(Litre::from(CubicMetre(1.)), Litre(1000.)) } }