1use serde::de::Error;
2use serde::{Deserialize, Deserializer};
3use serde_json::Value;
4use std::fmt::Formatter;
5use std::str::FromStr;
6
7pub fn string_or_number_to_u8<'de, D>(deserializer: D) -> Result<u8, D::Error>
8where
9 D: serde::Deserializer<'de>,
10{
11 struct StringOrNumberVisitor;
12
13 impl<'de> serde::de::Visitor<'de> for StringOrNumberVisitor {
14 type Value = u8;
15
16 fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
17 formatter.write_str("a string or an integer")
18 }
19
20 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
21 where
22 E: Error,
23 {
24 u8::from_str(v).map_err(serde::de::Error::custom)
25 }
26
27 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
28 where
29 E: Error,
30 {
31 if v <= u8::MAX as u64 {
32 Ok(v as u8)
33 } else {
34 Err(E::custom(format!("u64 value {v} is out of range for u8")))
35 }
36 }
37 }
38
39 deserializer.deserialize_any(StringOrNumberVisitor)
40}
41
42pub fn string_or_number_to_u16<'de, D>(deserializer: D) -> Result<u16, D::Error>
43where
44 D: serde::Deserializer<'de>,
45{
46 struct StringOrNumberVisitor;
47
48 impl<'de> serde::de::Visitor<'de> for StringOrNumberVisitor {
49 type Value = u16;
50
51 fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
52 formatter.write_str("a string or an integer")
53 }
54
55 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
56 where
57 E: Error,
58 {
59 u16::from_str(v).map_err(serde::de::Error::custom)
60 }
61
62 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
63 where
64 E: Error,
65 {
66 if v <= u16::MAX as u64 {
67 Ok(v as u16)
68 } else {
69 Err(E::custom(format!("u64 value {v} is out of range for u16")))
70 }
71 }
72 }
73
74 deserializer.deserialize_any(StringOrNumberVisitor)
75}
76
77pub fn string_or_number_to_u32<'de, D>(deserializer: D) -> Result<u32, D::Error>
78where
79 D: serde::Deserializer<'de>,
80{
81 struct StringOrNumberVisitor;
82
83 impl<'de> serde::de::Visitor<'de> for StringOrNumberVisitor {
84 type Value = u32;
85
86 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
87 formatter.write_str("a string or an integer")
88 }
89
90 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
91 where
92 E: Error,
93 {
94 u32::from_str(v).map_err(serde::de::Error::custom)
95 }
96
97 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
98 where
99 E: Error,
100 {
101 if v <= u32::MAX as u64 {
102 Ok(v as u32)
103 } else {
104 Err(E::custom(format!("u64 value {v} is out of range for u32")))
105 }
106 }
107 }
108
109 deserializer.deserialize_any(StringOrNumberVisitor)
110}
111
112pub fn option_string_or_number_to_u8<'de, D>(deserializer: D) -> Result<Option<u8>, D::Error>
113where
114 D: serde::Deserializer<'de>,
115{
116 struct OptionStringOrNumberVisitor;
117
118 impl<'de> serde::de::Visitor<'de> for OptionStringOrNumberVisitor {
119 type Value = Option<u8>;
120
121 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
122 formatter.write_str("an optional u8, either as a number, a string, or null")
123 }
124
125 fn visit_none<E>(self) -> Result<Self::Value, E>
126 where
127 E: Error,
128 {
129 Ok(None)
130 }
131
132 fn visit_unit<E>(self) -> Result<Self::Value, E>
133 where
134 E: Error,
135 {
136 Ok(None)
137 }
138
139 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
140 where
141 D: serde::Deserializer<'de>,
142 {
143 super::string_or_number_to_u8(deserializer).map(Some)
145 }
146 }
147
148 deserializer.deserialize_option(OptionStringOrNumberVisitor)
149}
150
151pub fn option_string_or_number_to_u16<'de, D>(deserializer: D) -> Result<Option<u16>, D::Error>
152where
153 D: serde::Deserializer<'de>,
154{
155 struct OptionStringOrNumberVisitor;
156
157 impl<'de> serde::de::Visitor<'de> for OptionStringOrNumberVisitor {
158 type Value = Option<u16>;
159
160 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
161 formatter.write_str("an optional u8, either as a number, a string, or null")
162 }
163
164 fn visit_none<E>(self) -> Result<Self::Value, E>
165 where
166 E: Error,
167 {
168 Ok(None)
169 }
170
171 fn visit_unit<E>(self) -> Result<Self::Value, E>
172 where
173 E: Error,
174 {
175 Ok(None)
176 }
177
178 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
179 where
180 D: serde::Deserializer<'de>,
181 {
182 super::string_or_number_to_u16(deserializer).map(Some)
184 }
185 }
186
187 deserializer.deserialize_option(OptionStringOrNumberVisitor)
188}
189
190pub fn bool_from_int_or_bool<'de, D>(deserializer: D) -> Result<Option<bool>, D::Error>
191where
192 D: Deserializer<'de>,
193{
194 let v: Option<Value> = Option::deserialize(deserializer)?;
195 match v {
196 Some(Value::Bool(b)) => Ok(Some(b)),
197 Some(Value::Number(n)) => {
198 if let Some(i) = n.as_i64() {
199 Ok(Some(i != 0))
200 } else {
201 Err(serde::de::Error::custom("Invalid number for bool"))
202 }
203 }
204 Some(Value::Null) | None => Ok(None),
205 _ => Err(serde::de::Error::custom("Expected bool or int")),
206 }
207}