serde_with/rust.rs
1//! De/Serialization for Rust's builtin and std types
2
3use crate::prelude::*;
4
5/// Makes a distinction between a missing, unset, or existing value
6///
7/// Some serialization formats make a distinction between missing fields, fields with a `null`
8/// value, and existing values. One such format is JSON. By default it is not easily possible to
9/// differentiate between a missing value and a field which is `null`, as they deserialize to the
10/// same value. This helper changes it, by using an `Option<Option<T>>` to deserialize into.
11///
12/// * `None`: Represents a missing value.
13/// * `Some(None)`: Represents a `null` value.
14/// * `Some(Some(value))`: Represents an existing value.
15///
16/// Note: This cannot be made compatible to `serde_as`, since skipping of values is only available on the field level.
17/// A hypothetical `DoubleOption<T>` with a `SerializeAs` implementation would allow writing something like this.
18/// This cannot work, since there is no way to tell the `Vec` to skip the inner `DoubleOption` if it is `None`.
19///
20/// ```rust
21/// # #[cfg(any())] {
22/// # struct Foobar {
23/// #[serde_as(as = "Vec<DoubleOption<_>>")]
24/// data: Vec<Option<Option<i32>>>,
25/// # }
26/// # }
27/// ```
28///
29/// # Examples
30///
31/// ```rust
32/// # use serde::{Deserialize, Serialize};
33/// #
34/// # #[derive(Debug, PartialEq, Eq)]
35/// #[derive(Deserialize, Serialize)]
36/// struct Doc {
37/// #[serde(
38/// default, // <- important for deserialization
39/// skip_serializing_if = "Option::is_none", // <- important for serialization
40/// with = "::serde_with::rust::double_option",
41/// )]
42/// a: Option<Option<u8>>,
43/// }
44/// // Missing Value
45/// let s = r#"{}"#;
46/// assert_eq!(Doc { a: None }, serde_json::from_str(s).unwrap());
47/// assert_eq!(s, serde_json::to_string(&Doc { a: None }).unwrap());
48///
49/// // Unset Value
50/// let s = r#"{"a":null}"#;
51/// assert_eq!(Doc { a: Some(None) }, serde_json::from_str(s).unwrap());
52/// assert_eq!(s, serde_json::to_string(&Doc { a: Some(None) }).unwrap());
53///
54/// // Existing Value
55/// let s = r#"{"a":5}"#;
56/// assert_eq!(Doc { a: Some(Some(5)) }, serde_json::from_str(s).unwrap());
57/// assert_eq!(s, serde_json::to_string(&Doc { a: Some(Some(5)) }).unwrap());
58/// ```
59#[allow(clippy::option_option)]
60pub mod double_option {
61 use super::*;
62
63 /// Deserialize potentially non-existing optional value
64 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<Option<Option<T>>, D::Error>
65 where
66 T: Deserialize<'de>,
67 D: Deserializer<'de>,
68 {
69 Deserialize::deserialize(deserializer).map(Some)
70 }
71
72 /// Serialize optional value
73 pub fn serialize<S, T>(values: &Option<Option<T>>, serializer: S) -> Result<S::Ok, S::Error>
74 where
75 S: Serializer,
76 T: Serialize,
77 {
78 match values {
79 None => serializer.serialize_unit(),
80 Some(None) => serializer.serialize_none(),
81 Some(Some(v)) => serializer.serialize_some(&v),
82 }
83 }
84}
85
86/// Serialize inner value if [`Some`]`(T)`. If [`None`], serialize the unit struct `()`.
87///
88/// When used in conjunction with `skip_serializing_if = "Option::is_none"` and
89/// `default`, you can build an optional value by skipping if it is [`None`], or serializing its
90/// inner value if [`Some`]`(T)`.
91///
92/// Not all serialization formats easily support optional values.
93/// While JSON uses the [`Option`] type to represent optional values and only serializes the inner
94/// part of the [`Some`]`()`, other serialization formats, such as [RON][], choose to serialize the
95/// [`Some`] around a value.
96/// This helper helps building a truly optional value for such serializers.
97///
98/// [RON]: https://github.com/ron-rs/ron
99///
100/// # Example
101///
102/// ```rust
103/// # use serde::{Deserialize, Serialize};
104/// #
105/// # #[derive(Debug, Eq, PartialEq)]
106/// #[derive(Deserialize, Serialize)]
107/// struct Doc {
108/// mandatory: usize,
109/// #[serde(
110/// default, // <- important for deserialization
111/// skip_serializing_if = "Option::is_none", // <- important for serialization
112/// with = "::serde_with::rust::unwrap_or_skip",
113/// )]
114/// optional: Option<usize>,
115/// }
116///
117/// // Transparently add/remove Some() wrapper
118/// # let pretty_config = ron::ser::PrettyConfig::new()
119/// # .new_line("\n".into());
120/// let s = r#"(
121/// mandatory: 1,
122/// optional: 2,
123/// )"#;
124/// let v = Doc {
125/// mandatory: 1,
126/// optional: Some(2),
127/// };
128/// assert_eq!(v, ron::de::from_str(s).unwrap());
129/// assert_eq!(s, ron::ser::to_string_pretty(&v, pretty_config).unwrap());
130///
131/// // Missing values are deserialized as `None`
132/// // while `None` values are skipped during serialization.
133/// # let pretty_config = ron::ser::PrettyConfig::new()
134/// # .new_line("\n".into());
135/// let s = r#"(
136/// mandatory: 1,
137/// )"#;
138/// let v = Doc {
139/// mandatory: 1,
140/// optional: None,
141/// };
142/// assert_eq!(v, ron::de::from_str(s).unwrap());
143/// assert_eq!(s, ron::ser::to_string_pretty(&v, pretty_config).unwrap());
144/// ```
145pub mod unwrap_or_skip {
146 use super::*;
147
148 /// Deserialize value wrapped in Some(T)
149 pub fn deserialize<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
150 where
151 D: Deserializer<'de>,
152 T: DeserializeOwned,
153 {
154 T::deserialize(deserializer).map(Some)
155 }
156
157 /// Serialize value if Some(T), unit struct if None
158 pub fn serialize<T, S>(option: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
159 where
160 T: Serialize,
161 S: Serializer,
162 {
163 if let Some(value) = option {
164 value.serialize(serializer)
165 } else {
166 ().serialize(serializer)
167 }
168 }
169}
170
171/// Ensure no duplicate values exist in a set.
172///
173/// By default serde has a last-value-wins implementation, if duplicate values for a set exist.
174/// Sometimes it is desirable to know when such an event happens, as the first value is overwritten
175/// and it can indicate an error in the serialized data.
176///
177/// This helper returns an error if two identical values exist in a set.
178///
179/// The implementation supports both the [`HashSet`] and the [`BTreeSet`] from the standard library.
180///
181/// # Converting to `serde_as`
182///
183/// The same functionality can be more clearly expressed using the `serde_as` macro and [`SetPreventDuplicates`].
184/// The `_` is a placeholder which works for any type which implements [`Serialize`]/[`Deserialize`].
185///
186/// ```rust
187/// # #[cfg(any())] {
188/// #[serde_as]
189/// #[derive(Deserialize, Serialize)]
190/// struct A {
191/// #[serde_as(as = "SetPreventDuplicates<_, _>")]
192/// s: HashSet<usize>,
193/// }
194/// # }
195/// ```
196///
197/// [`HashSet`]: std::collections::HashSet
198/// [`BTreeSet`]: std::collections::HashSet
199///
200/// # Example
201///
202/// ```rust
203/// # use std::collections::HashSet;
204/// # use serde::Deserialize;
205/// #
206/// # #[derive(Debug, Eq, PartialEq)]
207/// #[derive(Deserialize)]
208/// struct Doc {
209/// #[serde(with = "::serde_with::rust::sets_duplicate_value_is_error")]
210/// set: HashSet<usize>,
211/// }
212///
213/// // Sets are serialized normally,
214/// let s = r#"{"set": [1, 2, 3, 4]}"#;
215/// let v = Doc {
216/// set: HashSet::from_iter(vec![1, 2, 3, 4]),
217/// };
218/// assert_eq!(v, serde_json::from_str(s).unwrap());
219///
220/// // but create an error if duplicate values, like the `1`, exist.
221/// let s = r#"{"set": [1, 2, 3, 4, 1]}"#;
222/// let res: Result<Doc, _> = serde_json::from_str(s);
223/// assert!(res.is_err());
224/// ```
225#[cfg(feature = "alloc")]
226pub mod sets_duplicate_value_is_error {
227 use super::*;
228 use crate::duplicate_key_impls::PreventDuplicateInsertsSet;
229
230 /// Deserialize a set and return an error on duplicate values
231 pub fn deserialize<'de, D, T, V>(deserializer: D) -> Result<T, D::Error>
232 where
233 T: PreventDuplicateInsertsSet<V>,
234 V: Deserialize<'de>,
235 D: Deserializer<'de>,
236 {
237 struct SeqVisitor<T, V> {
238 marker: PhantomData<T>,
239 set_item_type: PhantomData<V>,
240 }
241
242 impl<'de, T, V> Visitor<'de> for SeqVisitor<T, V>
243 where
244 T: PreventDuplicateInsertsSet<V>,
245 V: Deserialize<'de>,
246 {
247 type Value = T;
248
249 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
250 formatter.write_str("a sequence")
251 }
252
253 #[inline]
254 fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
255 where
256 A: SeqAccess<'de>,
257 {
258 let mut values = Self::Value::new(access.size_hint());
259
260 while let Some(value) = access.next_element()? {
261 if !values.insert(value) {
262 return Err(DeError::custom("invalid entry: found duplicate value"));
263 };
264 }
265
266 Ok(values)
267 }
268 }
269
270 let visitor = SeqVisitor {
271 marker: PhantomData,
272 set_item_type: PhantomData,
273 };
274 deserializer.deserialize_seq(visitor)
275 }
276
277 /// Serialize the set with the default serializer
278 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
279 where
280 T: Serialize,
281 S: Serializer,
282 {
283 value.serialize(serializer)
284 }
285}
286
287/// Ensure no duplicate keys exist in a map.
288///
289/// By default serde has a last-value-wins implementation, if duplicate keys for a map exist.
290/// Sometimes it is desirable to know when such an event happens, as the first value is overwritten
291/// and it can indicate an error in the serialized data.
292///
293/// This helper returns an error if two identical keys exist in a map.
294///
295/// The implementation supports both the [`HashMap`] and the [`BTreeMap`] from the standard library.
296///
297/// # Converting to `serde_as`
298///
299/// The same functionality can be more clearly expressed using the `serde_as` macro and [`MapPreventDuplicates`].
300/// The `_` is a placeholder which works for any type which implements [`Serialize`]/[`Deserialize`].
301///
302/// ```rust
303/// # #[cfg(any())] {
304/// #[serde_as]
305/// #[derive(Deserialize, Serialize)]
306/// struct A {
307/// #[serde_as(as = "MapPreventDuplicates<_, _>")]
308/// s: HashMap<usize, usize>,
309/// }
310/// # }
311/// ```
312///
313/// [`HashMap`]: std::collections::HashMap
314/// [`BTreeMap`]: std::collections::HashMap
315///
316/// # Example
317///
318/// ```rust
319/// # use serde::Deserialize;
320/// # use std::collections::HashMap;
321/// #
322/// # #[derive(Debug, Eq, PartialEq)]
323/// #[derive(Deserialize)]
324/// struct Doc {
325/// #[serde(with = "::serde_with::rust::maps_duplicate_key_is_error")]
326/// map: HashMap<usize, usize>,
327/// }
328///
329/// // Maps are serialized normally,
330/// let s = r#"{"map": {"1": 1, "2": 2, "3": 3}}"#;
331/// let mut v = Doc {
332/// map: HashMap::new(),
333/// };
334/// v.map.insert(1, 1);
335/// v.map.insert(2, 2);
336/// v.map.insert(3, 3);
337/// assert_eq!(v, serde_json::from_str(s).unwrap());
338///
339/// // but create an error if duplicate keys, like the `1`, exist.
340/// let s = r#"{"map": {"1": 1, "2": 2, "1": 3}}"#;
341/// let res: Result<Doc, _> = serde_json::from_str(s);
342/// assert!(res.is_err());
343/// ```
344#[cfg(feature = "alloc")]
345pub mod maps_duplicate_key_is_error {
346 use super::*;
347 use crate::duplicate_key_impls::PreventDuplicateInsertsMap;
348
349 /// Deserialize a map and return an error on duplicate keys
350 pub fn deserialize<'de, D, T, K, V>(deserializer: D) -> Result<T, D::Error>
351 where
352 T: PreventDuplicateInsertsMap<K, V>,
353 K: Deserialize<'de>,
354 V: Deserialize<'de>,
355 D: Deserializer<'de>,
356 {
357 struct MapVisitor<T, K, V> {
358 marker: PhantomData<T>,
359 map_key_type: PhantomData<K>,
360 map_value_type: PhantomData<V>,
361 }
362
363 impl<'de, T, K, V> Visitor<'de> for MapVisitor<T, K, V>
364 where
365 T: PreventDuplicateInsertsMap<K, V>,
366 K: Deserialize<'de>,
367 V: Deserialize<'de>,
368 {
369 type Value = T;
370
371 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
372 formatter.write_str("a map")
373 }
374
375 #[inline]
376 fn visit_map<A>(self, mut access: A) -> Result<Self::Value, A::Error>
377 where
378 A: MapAccess<'de>,
379 {
380 let mut values = Self::Value::new(access.size_hint());
381
382 while let Some((key, value)) = access.next_entry()? {
383 if !values.insert(key, value) {
384 return Err(DeError::custom("invalid entry: found duplicate key"));
385 };
386 }
387
388 Ok(values)
389 }
390 }
391
392 let visitor = MapVisitor {
393 marker: PhantomData,
394 map_key_type: PhantomData,
395 map_value_type: PhantomData,
396 };
397 deserializer.deserialize_map(visitor)
398 }
399
400 /// Serialize the map with the default serializer
401 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
402 where
403 T: Serialize,
404 S: Serializer,
405 {
406 value.serialize(serializer)
407 }
408}
409
410/// Ensure that the last value is taken, if duplicate values exist
411///
412/// By default serde has a first-value-wins implementation, if duplicate keys for a set exist.
413/// Sometimes the opposite strategy is desired. This helper implements a first-value-wins strategy.
414///
415/// The implementation supports both the [`HashSet`] and the [`BTreeSet`] from the standard library.
416///
417/// # Converting to `serde_as`
418///
419/// The same functionality can be more clearly expressed using the `serde_as` macro and [`SetLastValueWins`].
420/// The `_` is a placeholder which works for any type which implements [`Serialize`]/[`Deserialize`].
421///
422/// ```rust
423/// # #[cfg(any())] {
424/// #[serde_as]
425/// #[derive(Deserialize, Serialize)]
426/// struct A {
427/// #[serde_as(as = "SetLastValueWins<_, _>")]
428/// s: HashSet<usize>,
429/// }
430/// # }
431/// ```
432///
433/// [`HashSet`]: std::collections::HashSet
434/// [`BTreeSet`]: std::collections::HashSet
435#[cfg(feature = "alloc")]
436pub mod sets_last_value_wins {
437 use super::*;
438 use crate::duplicate_key_impls::DuplicateInsertsLastWinsSet;
439
440 /// Deserialize a set and keep the last of equal values
441 pub fn deserialize<'de, D, T, V>(deserializer: D) -> Result<T, D::Error>
442 where
443 T: DuplicateInsertsLastWinsSet<V>,
444 V: Deserialize<'de>,
445 D: Deserializer<'de>,
446 {
447 struct SeqVisitor<T, V> {
448 marker: PhantomData<T>,
449 set_item_type: PhantomData<V>,
450 }
451
452 impl<'de, T, V> Visitor<'de> for SeqVisitor<T, V>
453 where
454 T: DuplicateInsertsLastWinsSet<V>,
455 V: Deserialize<'de>,
456 {
457 type Value = T;
458
459 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
460 formatter.write_str("a sequence")
461 }
462
463 #[inline]
464 fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
465 where
466 A: SeqAccess<'de>,
467 {
468 let mut values = Self::Value::new(access.size_hint());
469
470 while let Some(value) = access.next_element()? {
471 values.replace(value);
472 }
473
474 Ok(values)
475 }
476 }
477
478 let visitor = SeqVisitor {
479 marker: PhantomData,
480 set_item_type: PhantomData,
481 };
482 deserializer.deserialize_seq(visitor)
483 }
484
485 /// Serialize the set with the default serializer
486 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
487 where
488 T: Serialize,
489 S: Serializer,
490 {
491 value.serialize(serializer)
492 }
493}
494
495/// Ensure that the first key is taken, if duplicate keys exist
496///
497/// By default serde has a last-key-wins implementation, if duplicate keys for a map exist.
498/// Sometimes the opposite strategy is desired. This helper implements a first-key-wins strategy.
499///
500/// The implementation supports both the [`HashMap`] and the [`BTreeMap`] from the standard library.
501///
502/// [`HashMap`]: std::collections::HashMap
503/// [`BTreeMap`]: std::collections::HashMap
504///
505/// # Converting to `serde_as`
506///
507/// The same functionality can be more clearly expressed using the `serde_as` macro and [`MapFirstKeyWins`].
508/// The `_` is a placeholder which works for any type which implements [`Serialize`]/[`Deserialize`].
509///
510/// ```rust
511/// # #[cfg(any())] {
512/// #[serde_as]
513/// #[derive(Deserialize, Serialize)]
514/// struct A {
515/// #[serde_as(as = "MapFirstKeyWins<_, _>")]
516/// s: HashMap<usize, usize>,
517/// }
518/// # }
519/// ```
520///
521/// # Example
522///
523/// ```rust
524/// # use serde::Deserialize;
525/// # use std::collections::HashMap;
526/// #
527/// # #[derive(Debug, Eq, PartialEq)]
528/// #[derive(Deserialize)]
529/// struct Doc {
530/// #[serde(with = "::serde_with::rust::maps_first_key_wins")]
531/// map: HashMap<usize, usize>,
532/// }
533///
534/// // Maps are serialized normally,
535/// let s = r#"{"map": {"1": 1, "2": 2, "3": 3}}"#;
536/// let mut v = Doc {
537/// map: HashMap::new(),
538/// };
539/// v.map.insert(1, 1);
540/// v.map.insert(2, 2);
541/// v.map.insert(3, 3);
542/// assert_eq!(v, serde_json::from_str(s).unwrap());
543///
544/// // but create an error if duplicate keys, like the `1`, exist.
545/// let s = r#"{"map": {"1": 1, "2": 2, "1": 3}}"#;
546/// let mut v = Doc {
547/// map: HashMap::new(),
548/// };
549/// v.map.insert(1, 1);
550/// v.map.insert(2, 2);
551/// assert_eq!(v, serde_json::from_str(s).unwrap());
552/// ```
553#[cfg(feature = "alloc")]
554pub mod maps_first_key_wins {
555 use super::*;
556 use crate::duplicate_key_impls::DuplicateInsertsFirstWinsMap;
557
558 /// Deserialize a map and return an error on duplicate keys
559 pub fn deserialize<'de, D, T, K, V>(deserializer: D) -> Result<T, D::Error>
560 where
561 T: DuplicateInsertsFirstWinsMap<K, V>,
562 K: Deserialize<'de>,
563 V: Deserialize<'de>,
564 D: Deserializer<'de>,
565 {
566 struct MapVisitor<T, K, V> {
567 marker: PhantomData<T>,
568 map_key_type: PhantomData<K>,
569 map_value_type: PhantomData<V>,
570 }
571
572 impl<'de, T, K, V> Visitor<'de> for MapVisitor<T, K, V>
573 where
574 T: DuplicateInsertsFirstWinsMap<K, V>,
575 K: Deserialize<'de>,
576 V: Deserialize<'de>,
577 {
578 type Value = T;
579
580 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
581 formatter.write_str("a map")
582 }
583
584 #[inline]
585 fn visit_map<A>(self, mut access: A) -> Result<Self::Value, A::Error>
586 where
587 A: MapAccess<'de>,
588 {
589 let mut values = Self::Value::new(access.size_hint());
590
591 while let Some((key, value)) = access.next_entry()? {
592 values.insert(key, value);
593 }
594
595 Ok(values)
596 }
597 }
598
599 let visitor = MapVisitor {
600 marker: PhantomData,
601 map_key_type: PhantomData,
602 map_value_type: PhantomData,
603 };
604 deserializer.deserialize_map(visitor)
605 }
606
607 /// Serialize the map with the default serializer
608 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
609 where
610 T: Serialize,
611 S: Serializer,
612 {
613 value.serialize(serializer)
614 }
615}
616
617/// Deserialize any value, ignore it, and return the default value for the type being deserialized.
618///
619/// This function can be used in two different ways:
620///
621/// 1. It is useful for instance to create an enum with a catch-all variant that will accept any incoming data.
622/// 2. [`untagged`] enum representations do not allow the `other` annotation as the fallback enum variant.
623/// With this function you can emulate an `other` variant, which can deserialize any data carrying enum.
624///
625/// **Note:** Using this function will prevent deserializing data-less enum variants.
626/// If this is a problem depends on the data format.
627/// For example, deserializing `"Bar"` as an enum in JSON would fail, since it carries no data.
628///
629/// # Examples
630///
631/// ## Deserializing a heterogeneous collection of XML nodes
632///
633/// When [`serde-xml-rs`] deserializes an XML tag to an enum, it always maps the tag
634/// name to the enum variant name, and the tag attributes and children to the enum contents.
635/// This means that in order for an enum variant to accept any XML tag, it both has to use
636/// `#[serde(other)]` to accept any tag name, and `#[serde(deserialize_with = "deserialize_ignore_any")]`
637/// to accept any attributes and children.
638///
639/// ```rust
640/// # use serde::Deserialize;
641/// use serde_with::rust::deserialize_ignore_any;
642///
643/// # #[derive(Debug, PartialEq)]
644/// #[derive(Deserialize)]
645/// #[serde(rename_all = "lowercase")]
646/// enum Item {
647/// Foo(String),
648/// Bar(String),
649/// #[serde(other, deserialize_with = "deserialize_ignore_any")]
650/// Other,
651/// }
652///
653/// // Deserialize this XML
654/// # let items: Vec<Item> = serde_xml_rs::from_str(
655/// r"
656/// <foo>a</foo>
657/// <bar>b</bar>
658/// <foo>c</foo>
659/// <unknown>d</unknown>
660/// "
661/// # ).unwrap();
662///
663/// // into these Items
664/// # let expected =
665/// vec![
666/// Item::Foo(String::from("a")),
667/// Item::Bar(String::from("b")),
668/// Item::Foo(String::from("c")),
669/// Item::Other,
670/// ]
671/// # ;
672/// # assert_eq!(expected, items);
673/// ```
674///
675/// ## Simulating an `other` enum variant in an `untagged` enum
676///
677/// ```rust
678/// # use serde::Deserialize;
679/// # use serde_json::json;
680/// use serde_with::rust::deserialize_ignore_any;
681///
682/// # #[derive(Debug, PartialEq)]
683/// #[derive(Deserialize)]
684/// #[serde(untagged)]
685/// enum Item {
686/// Foo{x: u8},
687/// #[serde(deserialize_with = "deserialize_ignore_any")]
688/// Other,
689/// }
690///
691/// // Deserialize this JSON
692/// # let items: Vec<Item> = serde_json::from_value(
693/// json!([
694/// {"y": 1},
695/// {"x": 1},
696/// ])
697/// # ).unwrap();
698///
699/// // into these Items
700/// # let expected =
701/// vec![Item::Other, Item::Foo{x: 1}]
702/// # ;
703/// # assert_eq!(expected, items);
704/// ```
705///
706/// [`serde-xml-rs`]: https://docs.rs/serde-xml-rs
707/// [`untagged`]: https://serde.rs/enum-representations.html#untagged
708pub fn deserialize_ignore_any<'de, D: Deserializer<'de>, T: Default>(
709 deserializer: D,
710) -> Result<T, D::Error> {
711 IgnoredAny::deserialize(deserializer).map(|_| T::default())
712}