#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum Unit {
Feet,
Metres,
}
impl Unit {
pub fn metres_per_unit(self) -> f64 {
match self {
Unit::Feet => petektools::units::FT_TO_M,
Unit::Metres => 1.0,
}
}
pub fn convert(self, value: f64, to: Unit) -> f64 {
value * self.metres_per_unit() / to.metres_per_unit()
}
pub fn area_to_m2(self, area_in_unit_sq: f64) -> f64 {
let m = self.metres_per_unit();
area_in_unit_sq * m * m
}
}
#[cfg(test)]
mod tests {
use super::*;
use approx::assert_relative_eq;
#[test]
fn feet_to_metres_roundtrip() {
assert_relative_eq!(Unit::Feet.convert(100.0, Unit::Metres), 30.48);
assert_relative_eq!(Unit::Metres.convert(30.48, Unit::Feet), 100.0);
assert_relative_eq!(Unit::Feet.convert(42.0, Unit::Feet), 42.0);
}
#[test]
fn area_to_m2_hand_calc() {
assert_relative_eq!(Unit::Feet.area_to_m2(1.0), 0.092_903_04, epsilon = 1e-9);
assert_relative_eq!(Unit::Metres.area_to_m2(4_046.856_422_4), 4_046.856_422_4);
}
}