aboutsummaryrefslogtreecommitdiffstats
path: root/src/volume
diff options
context:
space:
mode:
Diffstat (limited to 'src/volume')
-rw-r--r--src/volume/cubic_centimetre.rs16
-rw-r--r--src/volume/cubic_metre.rs26
-rw-r--r--src/volume/litre.rs16
-rw-r--r--src/volume/mod.rs70
-rw-r--r--src/volume/unit.rs27
5 files changed, 155 insertions, 0 deletions
diff --git a/src/volume/cubic_centimetre.rs b/src/volume/cubic_centimetre.rs
new file mode 100644
index 0000000..760a3f3
--- /dev/null
+++ b/src/volume/cubic_centimetre.rs
@@ -0,0 +1,16 @@
+use super::{CubicMetre, Litre};
+
+#[derive(Debug, PartialEq)]
+pub struct CubicCentimetre(pub f64);
+
+impl From<CubicMetre> for CubicCentimetre {
+ fn from(value: CubicMetre) -> Self {
+ Self(value.0 * 10_f64.powi(6))
+ }
+}
+
+impl From<Litre> for CubicCentimetre {
+ fn from(value: Litre) -> Self {
+ Self(value.0 * 10_f64.powi(3))
+ }
+}
diff --git a/src/volume/cubic_metre.rs b/src/volume/cubic_metre.rs
new file mode 100644
index 0000000..a908b11
--- /dev/null
+++ b/src/volume/cubic_metre.rs
@@ -0,0 +1,26 @@
+use super::{CubicCentimetre, Litre, Unit};
+
+#[derive(Debug, Default, PartialEq)]
+pub struct CubicMetre(pub f64);
+
+impl CubicMetre {
+ pub fn from_unit<F: Into<f64>>(unit: Unit, value: F) -> Self {
+ match unit {
+ Unit::CubicMetre => Self(value.into()),
+ Unit::Litre => Self::from(Litre(value.into())),
+ Unit::CubicCentimetre => Self::from(CubicCentimetre(value.into())),
+ }
+ }
+}
+
+impl From<Litre> for CubicMetre {
+ fn from(value: Litre) -> Self {
+ Self(value.0 * 10_f64.powi(-3))
+ }
+}
+
+impl From<CubicCentimetre> for CubicMetre {
+ fn from(value: CubicCentimetre) -> Self {
+ Self(value.0 * 10_f64.powi(-6))
+ }
+}
diff --git a/src/volume/litre.rs b/src/volume/litre.rs
new file mode 100644
index 0000000..2b4e7c2
--- /dev/null
+++ b/src/volume/litre.rs
@@ -0,0 +1,16 @@
+use super::{CubicCentimetre, CubicMetre};
+
+#[derive(Debug, PartialEq)]
+pub struct Litre(pub f64);
+
+impl From<CubicMetre> for Litre {
+ fn from(value: CubicMetre) -> Self {
+ Self(value.0 * 10_f64.powi(3))
+ }
+}
+
+impl From<CubicCentimetre> for Litre {
+ fn from(value: CubicCentimetre) -> Self {
+ Self(value.0 * 10_f64.powi(-3))
+ }
+}
diff --git a/src/volume/mod.rs b/src/volume/mod.rs
new file mode 100644
index 0000000..0f36454
--- /dev/null
+++ b/src/volume/mod.rs
@@ -0,0 +1,70 @@
+mod cubic_centimetre;
+mod cubic_metre;
+mod litre;
+mod unit;
+
+pub use cubic_centimetre::CubicCentimetre;
+pub use cubic_metre::CubicMetre;
+pub use litre::Litre;
+pub use unit::Unit;
+
+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::CubicCentimetre => CubicCentimetre::from(CubicMetre(val.into())).0,
+ },
+ Unit::Litre => match to {
+ Unit::Litre => val.into(),
+ Unit::CubicMetre => CubicMetre::from(Litre(val.into())).0,
+ Unit::CubicCentimetre => CubicCentimetre::from(Litre(val.into())).0,
+ },
+ Unit::CubicCentimetre => match to {
+ Unit::CubicCentimetre => val.into(),
+ Unit::CubicMetre => CubicMetre::from(CubicCentimetre(val.into())).0,
+ Unit::Litre => Litre::from(CubicCentimetre(val.into())).0,
+ },
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::{CubicCentimetre, CubicMetre, Litre};
+
+ #[test]
+ fn cubic_metre_to_litre() {
+ assert_eq!(Litre::from(CubicMetre(1.)), Litre(1000.));
+ }
+
+ #[test]
+ fn cubic_metre_to_cubic_centimetre() {
+ assert_eq!(
+ CubicCentimetre::from(CubicMetre(1.)),
+ CubicCentimetre(1_000_000.)
+ );
+ }
+
+ #[test]
+ fn litre_to_cubic_metre() {
+ assert_eq!(CubicMetre::from(Litre(1000.)), CubicMetre(1.));
+ }
+
+ #[test]
+ fn litre_to_cubic_centimetre() {
+ assert_eq!(CubicCentimetre::from(Litre(1.)), CubicCentimetre(1000.));
+ }
+
+ #[test]
+ fn cubic_centimetre_to_cubic_metre() {
+ assert_eq!(
+ CubicMetre::from(CubicCentimetre(1_000_000.)),
+ CubicMetre(1.)
+ );
+ }
+
+ #[test]
+ fn cubic_centimetre_to_litre() {
+ assert_eq!(Litre::from(CubicCentimetre(1000.)), Litre(1.));
+ }
+}
diff --git a/src/volume/unit.rs b/src/volume/unit.rs
new file mode 100644
index 0000000..1b542d3
--- /dev/null
+++ b/src/volume/unit.rs
@@ -0,0 +1,27 @@
+use std::fmt::{self, Display, Formatter};
+
+#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
+pub enum Unit {
+ CubicMetre,
+ #[default]
+ Litre,
+ CubicCentimetre,
+}
+
+impl Unit {
+ pub const ALL: [Self; 3] = [Self::CubicMetre, Self::Litre, Self::CubicCentimetre];
+}
+
+impl Display for Unit {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "{}",
+ match self {
+ Self::CubicMetre => "m³",
+ Self::Litre => "L",
+ Self::CubicCentimetre => "cc",
+ }
+ )
+ }
+}