1use core::{convert::TryFrom as _, fmt};
2
3use serde::{
4 de::{self, Visitor},
5 Deserialize, Deserializer, Serialize, Serializer,
6};
7
8use crate::Weekday;
9
10pub mod serde_str {
11 use serde::{Deserializer, Serializer};
12
13 use super::{Weekday, WeekdayVisitor};
14
15 pub fn serialize<S>(weekday: &Weekday, serializer: S) -> Result<S::Ok, S::Error>
16 where
17 S: Serializer,
18 {
19 serializer.serialize_str(weekday.to_string().as_str())
20 }
21
22 pub fn deserialize<'de, D>(deserializer: D) -> Result<Weekday, D::Error>
23 where
24 D: Deserializer<'de>,
25 {
26 deserializer.deserialize_str(WeekdayVisitor)
27 }
28}
29
30pub mod serde_u64 {
31 use serde::{Deserializer, Serializer};
32
33 use super::{Weekday, WeekdayVisitor};
34
35 pub fn serialize<S>(weekday: &Weekday, serializer: S) -> Result<S::Ok, S::Error>
36 where
37 S: Serializer,
38 {
39 serializer.serialize_u64(weekday.to_owned() as u64)
40 }
41
42 pub fn deserialize<'de, D>(deserializer: D) -> Result<Weekday, D::Error>
43 where
44 D: Deserializer<'de>,
45 {
46 deserializer.deserialize_u64(WeekdayVisitor)
47 }
48}
49
50impl Serialize for Weekday {
51 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
52 where
53 S: Serializer,
54 {
55 serializer.serialize_str(self.to_string().as_str())
56 }
57}
58impl<'de> Deserialize<'de> for Weekday {
59 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
60 where
61 D: Deserializer<'de>,
62 {
63 deserializer.deserialize_any(WeekdayVisitor)
64 }
65}
66
67struct WeekdayVisitor;
68impl<'de> Visitor<'de> for WeekdayVisitor {
69 type Value = Weekday;
70
71 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
72 formatter.write_str("str or u8")
73 }
74
75 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
76 where
77 E: de::Error,
78 {
79 v.parse::<Self::Value>().map_err(de::Error::custom)
80 }
81
82 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
83 where
84 E: de::Error,
85 {
86 Self::Value::try_from(v as u8).map_err(de::Error::custom)
87 }
88
89 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
90 where
91 E: de::Error,
92 {
93 Self::Value::try_from(v as u8).map_err(de::Error::custom)
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 use serde_json::json;
102
103 #[derive(Deserialize, Serialize, PartialEq, Debug)]
104 struct Foo {
105 #[serde(with = "crate::serde_str")]
106 w1: Weekday,
107 #[serde(with = "crate::serde_u64")]
108 w2: Weekday,
109 #[serde(
110 serialize_with = "crate::serde_str::serialize",
111 deserialize_with = "crate::serde_u64::deserialize"
112 )]
113 w3: Weekday,
114 w4: Weekday,
115 }
116
117 #[test]
118 fn de() {
119 let json = r#"{ "w1": "Monday", "w2": 2, "w3": 3, "w4": "Thu" }"#;
120 assert_eq!(
121 serde_json::from_str::<Foo>(json).unwrap(),
122 Foo {
123 w1: Weekday::Mon,
124 w2: Weekday::Tue,
125 w3: Weekday::Wed,
126 w4: Weekday::Thu,
127 }
128 );
129
130 let json = r#"{ "w1": "Monday", "w2": 2, "w3": 3, "w4": 4 }"#;
131 assert_eq!(
132 serde_json::from_str::<Foo>(json).unwrap(),
133 Foo {
134 w1: Weekday::Mon,
135 w2: Weekday::Tue,
136 w3: Weekday::Wed,
137 w4: Weekday::Thu,
138 }
139 );
140 }
141
142 #[test]
143 fn ser() {
144 assert_eq!(
145 serde_json::to_value(&Foo {
146 w1: Weekday::Mon,
147 w2: Weekday::Tue,
148 w3: Weekday::Wed,
149 w4: Weekday::Thu,
150 })
151 .unwrap(),
152 json!({
153 "w1": "Mon", "w2": 2, "w3": "Wed", "w4": "Thu"
154 })
155 );
156 }
157}