1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#[derive(
Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, serde::Deserialize, serde::Serialize,
)]
#[serde(untagged)]
pub enum Length {
#[serde(rename = "cm")]
Centimeters,
#[serde(rename = "feet")]
Feet,
#[serde(rename = "inches")]
Inches,
#[serde(rename = "km")]
Kilometers,
#[serde(rename = "m")]
Meters,
}
#[derive(Clone, Debug, thiserror::Error)]
#[error("Could not parse units")]
pub struct LengthError;
impl Length {
pub fn is_centimeters(&self) -> bool {
match self {
Length::Centimeters => true,
_ => false,
}
}
pub fn is_feet(&self) -> bool {
match self {
Length::Feet => true,
_ => false,
}
}
pub fn is_inches(&self) -> bool {
match self {
Length::Inches => true,
_ => false,
}
}
pub fn is_kilometers(&self) -> bool {
match self {
Length::Kilometers => true,
_ => false,
}
}
pub fn is_meters(&self) -> bool {
match self {
Length::Meters => true,
_ => false,
}
}
}
impl Default for Length {
fn default() -> Self {
Length::Meters
}
}
impl std::str::FromStr for Length {
type Err = LengthError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"cm" => Ok(Length::Centimeters),
"feet" => Ok(Length::Feet),
"inches" => Ok(Length::Inches),
"km" => Ok(Length::Kilometers),
"m" => Ok(Length::Meters),
_ => Err(LengthError),
}
}
}
impl std::convert::TryFrom<&str> for Length {
type Error = LengthError;
fn try_from(s: &str) -> Result<Self, Self::Error> {
s.parse()
}
}
impl std::convert::TryFrom<&mut str> for Length {
type Error = LengthError;
fn try_from(s: &mut str) -> Result<Self, Self::Error> {
s.parse()
}
}
impl std::convert::TryFrom<String> for Length {
type Error = LengthError;
fn try_from(s: String) -> Result<Self, Self::Error> {
s.parse()
}
}
impl std::fmt::Display for Length {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Length::Centimeters => write!(f, "cm"),
Length::Feet => write!(f, "feet"),
Length::Inches => write!(f, "inches"),
Length::Kilometers => write!(f, "km"),
Length::Meters => write!(f, "meters"),
}
}
}