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 {} is out of range for u8", v)))
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!(
70 "u64 value {} is out of range for u16",
71 v
72 )))
73 }
74 }
75 }
76
77 deserializer.deserialize_any(StringOrNumberVisitor)
78}
79
80pub fn option_string_or_number_to_u8<'de, D>(deserializer: D) -> Result<Option<u8>, D::Error>
81where
82 D: serde::Deserializer<'de>,
83{
84 struct OptionStringOrNumberVisitor;
85
86 impl<'de> serde::de::Visitor<'de> for OptionStringOrNumberVisitor {
87 type Value = Option<u8>;
88
89 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
90 formatter.write_str("an optional u8, either as a number, a string, or null")
91 }
92
93 fn visit_none<E>(self) -> Result<Self::Value, E>
94 where
95 E: Error,
96 {
97 Ok(None)
98 }
99
100 fn visit_unit<E>(self) -> Result<Self::Value, E>
101 where
102 E: Error,
103 {
104 Ok(None)
105 }
106
107 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
108 where
109 D: serde::Deserializer<'de>,
110 {
111 super::string_or_number_to_u8(deserializer).map(Some)
113 }
114 }
115
116 deserializer.deserialize_option(OptionStringOrNumberVisitor)
117}
118
119pub fn option_string_or_number_to_u16<'de, D>(deserializer: D) -> Result<Option<u16>, D::Error>
120where
121 D: serde::Deserializer<'de>,
122{
123 struct OptionStringOrNumberVisitor;
124
125 impl<'de> serde::de::Visitor<'de> for OptionStringOrNumberVisitor {
126 type Value = Option<u16>;
127
128 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
129 formatter.write_str("an optional u8, either as a number, a string, or null")
130 }
131
132 fn visit_none<E>(self) -> Result<Self::Value, E>
133 where
134 E: Error,
135 {
136 Ok(None)
137 }
138
139 fn visit_unit<E>(self) -> Result<Self::Value, E>
140 where
141 E: Error,
142 {
143 Ok(None)
144 }
145
146 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
147 where
148 D: serde::Deserializer<'de>,
149 {
150 super::string_or_number_to_u16(deserializer).map(Some)
152 }
153 }
154
155 deserializer.deserialize_option(OptionStringOrNumberVisitor)
156}
157
158pub fn bool_from_int_or_bool<'de, D>(deserializer: D) -> Result<Option<bool>, D::Error>
159where
160 D: Deserializer<'de>,
161{
162 let v: Option<Value> = Option::deserialize(deserializer)?;
163 match v {
164 Some(Value::Bool(b)) => Ok(Some(b)),
165 Some(Value::Number(n)) => {
166 if let Some(i) = n.as_i64() {
167 Ok(Some(i != 0))
168 } else {
169 Err(serde::de::Error::custom("Invalid number for bool"))
170 }
171 }
172 Some(Value::Null) | None => Ok(None),
173 _ => Err(serde::de::Error::custom("Expected bool or int")),
174 }
175}