1use serde::de::value::SeqAccessDeserializer;
2use serde::ser::{Impossible, SerializeStructVariant, SerializeTupleVariant};
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use serde_json::Value;
5
6use std::error::Error;
7use std::fmt::{Display, Formatter};
8use std::marker::PhantomData;
9
10pub fn deserialize_untagged_enum_case_insensitive<'de, T, D>(deserializer: D) -> Result<T, D::Error>
47where
48 T: Deserialize<'de>,
49 D: Deserializer<'de>,
50{
51 T::deserialize(Value::String(
52 String::deserialize(deserializer)?.to_lowercase(),
53 ))
54 .map_err(serde::de::Error::custom)
55}
56
57pub fn deserialize_space_delimited_vec<'de, T, D>(deserializer: D) -> Result<T, D::Error>
89where
90 T: Default + Deserialize<'de>,
91 D: Deserializer<'de>,
92{
93 if let Some(space_delimited) = Option::<String>::deserialize(deserializer)? {
94 let entries = space_delimited
95 .split(' ')
96 .map(|s| Value::String(s.to_string()))
97 .collect();
98 T::deserialize(Value::Array(entries)).map_err(serde::de::Error::custom)
99 } else {
100 Ok(T::default())
102 }
103}
104
105pub fn deserialize_optional_string_or_vec_string<'de, D>(
107 deserializer: D,
108) -> Result<Option<Vec<String>>, D::Error>
109where
110 D: Deserializer<'de>,
111{
112 struct StringOrVec(PhantomData<Vec<String>>);
113
114 impl<'de> serde::de::Visitor<'de> for StringOrVec {
115 type Value = Option<Vec<String>>;
116
117 fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
118 formatter.write_str("string or list of strings")
119 }
120
121 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
122 where
123 E: serde::de::Error,
124 {
125 Ok(Some(vec![value.to_owned()]))
126 }
127
128 fn visit_none<E>(self) -> Result<Self::Value, E>
129 where
130 E: serde::de::Error,
131 {
132 Ok(None)
133 }
134
135 fn visit_unit<E>(self) -> Result<Self::Value, E>
136 where
137 E: serde::de::Error,
138 {
139 Ok(None)
140 }
141
142 fn visit_seq<S>(self, visitor: S) -> Result<Self::Value, S::Error>
143 where
144 S: serde::de::SeqAccess<'de>,
145 {
146 Deserialize::deserialize(SeqAccessDeserializer::new(visitor)).map(Some)
147 }
148 }
149
150 deserializer.deserialize_any(StringOrVec(PhantomData))
151}
152
153pub fn serialize_space_delimited_vec<T, S>(
159 vec_opt: &Option<Vec<T>>,
160 serializer: S,
161) -> Result<S::Ok, S::Error>
162where
163 T: AsRef<str>,
164 S: Serializer,
165{
166 if let Some(ref vec) = *vec_opt {
167 let space_delimited = vec.iter().map(|s| s.as_ref()).collect::<Vec<_>>().join(" ");
168
169 serializer.serialize_str(&space_delimited)
170 } else {
171 serializer.serialize_none()
172 }
173}
174
175pub fn variant_name<T: Serialize>(t: &T) -> &'static str {
180 #[derive(Debug)]
181 struct NotEnum;
182 type Result<T> = std::result::Result<T, NotEnum>;
183 impl Error for NotEnum {
184 fn description(&self) -> &str {
185 "not struct"
186 }
187 }
188 impl Display for NotEnum {
189 fn fmt(&self, _f: &mut Formatter) -> std::fmt::Result {
190 unimplemented!()
191 }
192 }
193 impl serde::ser::Error for NotEnum {
194 fn custom<T: Display>(_msg: T) -> Self {
195 NotEnum
196 }
197 }
198
199 struct VariantName;
200 impl Serializer for VariantName {
201 type Ok = &'static str;
202 type Error = NotEnum;
203 type SerializeSeq = Impossible<Self::Ok, Self::Error>;
204 type SerializeTuple = Impossible<Self::Ok, Self::Error>;
205 type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
206 type SerializeTupleVariant = Enum;
207 type SerializeMap = Impossible<Self::Ok, Self::Error>;
208 type SerializeStruct = Impossible<Self::Ok, Self::Error>;
209 type SerializeStructVariant = Enum;
210 fn serialize_bool(self, _v: bool) -> Result<Self::Ok> {
211 Err(NotEnum)
212 }
213 fn serialize_i8(self, _v: i8) -> Result<Self::Ok> {
214 Err(NotEnum)
215 }
216 fn serialize_i16(self, _v: i16) -> Result<Self::Ok> {
217 Err(NotEnum)
218 }
219 fn serialize_i32(self, _v: i32) -> Result<Self::Ok> {
220 Err(NotEnum)
221 }
222 fn serialize_i64(self, _v: i64) -> Result<Self::Ok> {
223 Err(NotEnum)
224 }
225 fn serialize_u8(self, _v: u8) -> Result<Self::Ok> {
226 Err(NotEnum)
227 }
228 fn serialize_u16(self, _v: u16) -> Result<Self::Ok> {
229 Err(NotEnum)
230 }
231 fn serialize_u32(self, _v: u32) -> Result<Self::Ok> {
232 Err(NotEnum)
233 }
234 fn serialize_u64(self, _v: u64) -> Result<Self::Ok> {
235 Err(NotEnum)
236 }
237 fn serialize_f32(self, _v: f32) -> Result<Self::Ok> {
238 Err(NotEnum)
239 }
240 fn serialize_f64(self, _v: f64) -> Result<Self::Ok> {
241 Err(NotEnum)
242 }
243 fn serialize_char(self, _v: char) -> Result<Self::Ok> {
244 Err(NotEnum)
245 }
246 fn serialize_str(self, _v: &str) -> Result<Self::Ok> {
247 Err(NotEnum)
248 }
249 fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok> {
250 Err(NotEnum)
251 }
252 fn serialize_none(self) -> Result<Self::Ok> {
253 Err(NotEnum)
254 }
255 fn serialize_some<T: ?Sized + Serialize>(self, _value: &T) -> Result<Self::Ok> {
256 Err(NotEnum)
257 }
258 fn serialize_unit(self) -> Result<Self::Ok> {
259 Err(NotEnum)
260 }
261 fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
262 Err(NotEnum)
263 }
264 fn serialize_unit_variant(
265 self,
266 _name: &'static str,
267 _variant_index: u32,
268 variant: &'static str,
269 ) -> Result<Self::Ok> {
270 Ok(variant)
271 }
272 fn serialize_newtype_struct<T: ?Sized + Serialize>(
273 self,
274 _name: &'static str,
275 _value: &T,
276 ) -> Result<Self::Ok> {
277 Err(NotEnum)
278 }
279 fn serialize_newtype_variant<T: ?Sized + Serialize>(
280 self,
281 _name: &'static str,
282 _variant_index: u32,
283 variant: &'static str,
284 _value: &T,
285 ) -> Result<Self::Ok> {
286 Ok(variant)
287 }
288 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
289 Err(NotEnum)
290 }
291 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
292 Err(NotEnum)
293 }
294 fn serialize_tuple_struct(
295 self,
296 _name: &'static str,
297 _len: usize,
298 ) -> Result<Self::SerializeTupleStruct> {
299 Err(NotEnum)
300 }
301 fn serialize_tuple_variant(
302 self,
303 _name: &'static str,
304 _variant_index: u32,
305 variant: &'static str,
306 _len: usize,
307 ) -> Result<Self::SerializeTupleVariant> {
308 Ok(Enum(variant))
309 }
310 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
311 Err(NotEnum)
312 }
313 fn serialize_struct(
314 self,
315 _name: &'static str,
316 _len: usize,
317 ) -> Result<Self::SerializeStruct> {
318 Err(NotEnum)
319 }
320 fn serialize_struct_variant(
321 self,
322 _name: &'static str,
323 _variant_index: u32,
324 variant: &'static str,
325 _len: usize,
326 ) -> Result<Self::SerializeStructVariant> {
327 Ok(Enum(variant))
328 }
329 }
330
331 struct Enum(&'static str);
332 impl SerializeStructVariant for Enum {
333 type Ok = &'static str;
334 type Error = NotEnum;
335 fn serialize_field<T: ?Sized + Serialize>(
336 &mut self,
337 _key: &'static str,
338 _value: &T,
339 ) -> Result<()> {
340 Ok(())
341 }
342 fn end(self) -> Result<Self::Ok> {
343 Ok(self.0)
344 }
345 }
346 impl SerializeTupleVariant for Enum {
347 type Ok = &'static str;
348 type Error = NotEnum;
349 fn serialize_field<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<()> {
350 Ok(())
351 }
352 fn end(self) -> Result<Self::Ok> {
353 Ok(self.0)
354 }
355 }
356
357 t.serialize(VariantName).unwrap()
358}
359
360#[cfg(test)]
361mod tests {
362 use serde::Deserialize;
363
364 #[derive(Deserialize, Debug, Clone)]
365 pub struct ObjectWithOptionalStringOrVecString {
366 #[serde(deserialize_with = "crate::helpers::deserialize_optional_string_or_vec_string")]
367 pub strings: Option<Vec<String>>,
368 }
369
370 #[test]
371 fn test_deserialize_optional_string_or_vec_string_none() {
372 let list_of_strings: ObjectWithOptionalStringOrVecString =
373 serde_json::from_str(r#"{ "strings": null }"#).unwrap();
374 assert_eq!(None, list_of_strings.strings);
375 }
376
377 #[test]
378 fn test_deserialize_optional_string_or_vec_string_single_value() {
379 let list_of_strings: ObjectWithOptionalStringOrVecString =
380 serde_json::from_str(r#"{ "strings": "v1" }"#).unwrap();
381 assert_eq!(Some(vec!["v1".to_string()]), list_of_strings.strings);
382 }
383
384 #[test]
385 fn test_deserialize_optional_string_or_vec_string_vec() {
386 let list_of_strings: ObjectWithOptionalStringOrVecString =
387 serde_json::from_str(r#"{ "strings": ["v1", "v2"] }"#).unwrap();
388 assert_eq!(
389 Some(vec!["v1".to_string(), "v2".to_string()]),
390 list_of_strings.strings
391 );
392 }
393}