activity_vocabulary/
lib.rs1#![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}