activity_vocabulary/
lib.rs

1#![allow(clippy::type_complexity, clippy::redundant_field_names)]
2use std::{fmt::Display, str::FromStr};
3
4use activity_vocabulary_core::*;
5use serde::{de::Visitor, Deserialize, Serialize};
6
7include!(concat!(env!("OUT_DIR"), "/vocab.rs"));
8
9#[derive(Clone, PartialEq, Eq, Debug, Hash, Default)]
10pub enum Unit {
11    Cm,
12    Feet,
13    Inches,
14    Km,
15    #[default]
16    M,
17    Miles,
18    Uri(url::Url),
19}
20
21impl Display for Unit {
22    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23        match self {
24            Self::Cm => f.write_str("cm"),
25            Self::Feet => f.write_str("feet"),
26            Self::Inches => f.write_str("inches"),
27            Self::Km => f.write_str("km"),
28            Self::M => f.write_str("m"),
29            Self::Miles => f.write_str("miles"),
30            Self::Uri(uri) => uri.fmt(f),
31        }
32    }
33}
34
35impl FromStr for Unit {
36    type Err = url::ParseError;
37
38    fn from_str(s: &str) -> Result<Self, Self::Err> {
39        Ok(match s {
40            "cm" => Self::Cm,
41            "feet" => Self::Feet,
42            "inches" => Self::Inches,
43            "km" => Self::Km,
44            "m" => Self::M,
45            "miles" => Self::Miles,
46            uri => Self::Uri(uri.parse()?),
47        })
48    }
49}
50
51impl Serialize for Unit {
52    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
53    where
54        S: serde::Serializer,
55    {
56        serializer.serialize_str(&self.to_string())
57    }
58}
59
60struct UnitVisitor;
61
62impl<'de> Visitor<'de> for UnitVisitor {
63    type Value = Unit;
64
65    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
66        formatter.write_str("Unit")
67    }
68
69    fn visit_none<E>(self) -> Result<Self::Value, E>
70    where
71        E: serde::de::Error,
72    {
73        Ok(Self::Value::default())
74    }
75
76    fn visit_unit<E>(self) -> Result<Self::Value, E>
77    where
78        E: serde::de::Error,
79    {
80        Ok(Self::Value::default())
81    }
82
83    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
84    where
85        E: serde::de::Error,
86    {
87        v.parse().map_err(serde::de::Error::custom)
88    }
89}
90
91impl<'de> Deserialize<'de> for Unit {
92    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
93    where
94        D: serde::Deserializer<'de>,
95    {
96        deserializer.deserialize_any(UnitVisitor)
97    }
98}