unitx_core/
distance.rs

1#[derive(Clone, Copy, Debug)]
2pub enum DistanceUnit {
3    M,
4    KM,
5    MI,
6}
7
8impl DistanceUnit {
9    pub fn parse(s: &str) -> Option<Self> {
10        match s.to_ascii_uppercase().as_str() {
11            "M" => Some(Self::M),
12            "KM" => Some(Self::KM),
13            "MI" => Some(Self::MI),
14            _ => None,
15        }
16    }
17}
18
19// constants (exact where possible)
20const M_PER_KM: f64 = 1000.0;
21const M_PER_MI: f64 = 1609.344; // exact statute mile in meters
22
23pub fn convert(value: f64, from: DistanceUnit, to: DistanceUnit) -> f64 {
24    // normalize to meters
25    let meters = match from {
26        DistanceUnit::M => value,
27        DistanceUnit::KM => value * M_PER_KM,
28        DistanceUnit::MI => value * M_PER_MI,
29    };
30    // meters -> target
31    match to {
32        DistanceUnit::M => meters,
33        DistanceUnit::KM => meters / M_PER_KM,
34        DistanceUnit::MI => meters / M_PER_MI,
35    }
36}