routee_compass_core/model/unit/
distance_unit.rs1use serde::{Deserialize, Serialize};
2use std::str::FromStr;
3use uom::si::f64::Length;
4
5#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Default)]
6#[serde(rename_all = "snake_case", try_from = "String")]
7pub enum DistanceUnit {
8 Meters,
9 Kilometers,
10 #[default]
11 Miles,
12 Inches,
13 Feet,
14}
15
16impl DistanceUnit {
17 pub fn to_uom(&self, value: f64) -> Length {
18 match self {
19 DistanceUnit::Meters => Length::new::<uom::si::length::meter>(value),
20 DistanceUnit::Kilometers => Length::new::<uom::si::length::kilometer>(value),
21 DistanceUnit::Miles => Length::new::<uom::si::length::mile>(value),
22 DistanceUnit::Inches => Length::new::<uom::si::length::inch>(value),
23 DistanceUnit::Feet => Length::new::<uom::si::length::foot>(value),
24 }
25 }
26 pub fn from_uom(&self, value: Length) -> f64 {
27 match self {
28 DistanceUnit::Meters => value.get::<uom::si::length::meter>(),
29 DistanceUnit::Kilometers => value.get::<uom::si::length::kilometer>(),
30 DistanceUnit::Miles => value.get::<uom::si::length::mile>(),
31 DistanceUnit::Inches => value.get::<uom::si::length::inch>(),
32 DistanceUnit::Feet => value.get::<uom::si::length::foot>(),
33 }
34 }
35}
36
37impl std::fmt::Display for DistanceUnit {
38 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39 let s = serde_json::to_string(self)
40 .map_err(|_| std::fmt::Error)?
41 .replace('\"', "");
42 write!(f, "{s}")
43 }
44}
45
46impl FromStr for DistanceUnit {
47 type Err = String;
48
49 fn from_str(s: &str) -> Result<Self, Self::Err> {
50 use DistanceUnit as D;
51 match s.trim().to_lowercase().as_str() {
52 "meters" | "meter" => Ok(D::Meters),
53 "km" | "kilometers" | "kilometer" => Ok(D::Kilometers),
54 "miles" | "mile" => Ok(D::Miles),
55 "inches" | "inch" | "in" => Ok(D::Inches),
56 "feet" | "ft" => Ok(D::Feet),
57 _ => Err(format!("unknown distance unit '{s}'")),
58 }
59 }
60}
61
62impl TryFrom<String> for DistanceUnit {
63 type Error = String;
64 fn try_from(value: String) -> Result<Self, Self::Error> {
65 Self::from_str(&value)
66 }
67}