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
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
pub enum Color {
Kok1,
Huok2,
}
#[must_use]
pub const fn serialize_color(color: Color) -> &'static str {
match color {
Color::Huok2 => "黒",
Color::Kok1 => "赤",
}
}
use std::str::FromStr;
impl FromStr for Color {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.to_lowercase();
match &*s {
"red" | "赤" | "kok1" | "红" | "紅" => Ok(Color::Kok1),
"black" | "黒" | "huok2" | "黑" => Ok(Color::Huok2),
_ => Err(()),
}
}
}
impl serde::ser::Serialize for Color {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(serialize_color(*self))
}
}
struct ColorVisitor;
impl<'de> serde::de::Visitor<'de> for ColorVisitor {
type Value = Color;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "a color")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Color::from_str(s).map_or_else(
|_| {
Err(serde::de::Error::invalid_value(
serde::de::Unexpected::Str(s),
&self,
))
},
|c| Ok(c),
)
}
}
impl<'de> serde::de::Deserialize<'de> for Color {
fn deserialize<D>(deserializer: D) -> Result<Color, D::Error>
where
D: serde::de::Deserializer<'de>,
{
deserializer.deserialize_str(ColorVisitor)
}
}
#[macro_export]
macro_rules! color {
('黒') => {
Color::Huok2
};
('赤') => {
Color::Kok1
};
}