aboutsummaryrefslogtreecommitdiffstats
path: root/src/volume.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/volume.rs')
-rw-r--r--src/volume.rs91
1 files changed, 33 insertions, 58 deletions
diff --git a/src/volume.rs b/src/volume.rs
index 675dfaa..933ae49 100644
--- a/src/volume.rs
+++ b/src/volume.rs
@@ -3,22 +3,17 @@ use std::{
ops::Mul,
};
-pub trait Volume {
- /// Returns the volume in SI units (cubic metres).
- fn si(self) -> CubicMetre;
-
- fn set(&mut self, val: f64);
-
- fn unit(&self) -> Unit;
-
- fn convert(self, unit: Unit) -> Box<dyn Volume>;
-}
-
+#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
pub enum Unit {
+ #[default]
CubicMetre,
Litre,
}
+impl Unit {
+ pub const ALL: [Self; 2] = [Self::CubicMetre, Self::Litre];
+}
+
impl Display for Unit {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
@@ -33,62 +28,29 @@ impl Display for Unit {
}
#[derive(Debug, Default, PartialEq)]
-pub struct CubicMetre(f64);
+pub struct CubicMetre(pub f64);
-impl Volume for CubicMetre {
- fn si(self) -> CubicMetre {
- self
- }
-
- fn set(&mut self, val: f64) {
- self.0 = val;
- }
-
- fn unit(&self) -> Unit {
- Unit::CubicMetre
- }
-
- fn convert(self, unit: Unit) -> Box<dyn Volume> {
+impl CubicMetre {
+ pub fn from_unit<F: Into<f64>>(unit: Unit, value: F) -> Self {
match unit {
- Unit::CubicMetre => Box::new(self),
- Unit::Litre => Box::new(Litre::from(self)),
+ Unit::CubicMetre => Self(value.into()),
+ Unit::Litre => Self::from(Litre(value.into())),
}
}
}
impl From<Litre> for CubicMetre {
fn from(value: Litre) -> Self {
- value.si()
+ Self(value.0 * 10_f64.powf(-3.))
}
}
#[derive(Debug, PartialEq)]
struct Litre(f64);
-impl Volume for Litre {
- fn si(self) -> CubicMetre {
- CubicMetre(self.0 * 10_f64.powf(-3.))
- }
-
- fn set(&mut self, val: f64) {
- self.0 = val
- }
-
- fn unit(&self) -> Unit {
- Unit::Litre
- }
-
- fn convert(self, unit: Unit) -> Box<dyn Volume> {
- match unit {
- Unit::CubicMetre => Box::new(CubicMetre::from(self)),
- Unit::Litre => Box::new(self),
- }
- }
-}
-
-impl From<i32> for Litre {
- fn from(value: i32) -> Self {
- Self(value as f64)
+impl<F: Into<f64>> From<F> for Litre {
+ fn from(value: F) -> Self {
+ Self(value.into())
}
}
@@ -98,21 +60,34 @@ impl From<CubicMetre> for Litre {
}
}
-impl Mul<f64> for Litre {
+impl<F: Into<f64>> Mul<F> for Litre {
type Output = Self;
- fn mul(self, rhs: f64) -> Self::Output {
- Self(self.0 * rhs)
+ fn mul(self, rhs: F) -> Self::Output {
+ Self(self.0 * rhs.into())
+ }
+}
+
+pub fn convert<F: Into<f64>>(val: F, from: Unit, to: Unit) -> f64 {
+ match from {
+ Unit::CubicMetre => match to {
+ Unit::CubicMetre => val.into(),
+ Unit::Litre => Litre::from(CubicMetre(val.into())).0,
+ },
+ Unit::Litre => match to {
+ Unit::Litre => val.into(),
+ Unit::CubicMetre => CubicMetre::from(Litre(val.into())).0,
+ },
}
}
#[cfg(test)]
mod tests {
- use crate::volume::{CubicMetre, Litre, Volume};
+ use super::{CubicMetre, Litre};
#[test]
fn litre_to_cubic_metre() {
- assert_eq!(Litre(1000.).si(), CubicMetre(1.))
+ assert_eq!(CubicMetre::from(Litre(1000.)), CubicMetre(1.))
}
#[test]