openconfiguration/
utils.rs1use std::collections::HashMap;
2use std::{fmt, hash::Hash, marker::PhantomData};
3
4use serde::{
5 de::{MapAccess, Visitor},
6 Deserialize, Deserializer,
7};
8
9pub fn deserialize_optional_map_without_null_values<'de, D, K, V>(
10 deserializer: D,
11) -> Result<Option<HashMap<K, V>>, D::Error>
12where
13 D: Deserializer<'de>,
14 K: Deserialize<'de> + Hash + Eq,
15 V: Deserialize<'de>,
16{
17 deserializer.deserialize_option(OptionSkipNullValuesMapVisitor {
18 marker: PhantomData,
19 })
20}
21
22pub fn deserialize_map_without_null_values<'de, D, K, V>(
23 deserializer: D,
24) -> Result<HashMap<K, V>, D::Error>
25where
26 D: Deserializer<'de>,
27 K: Deserialize<'de> + Hash + Eq,
28 V: Deserialize<'de>,
29{
30 deserializer.deserialize_map(SkipNullValuesMapVisitor {
31 marker: PhantomData,
32 })
33}
34
35struct SkipNullValuesMapVisitor<K, V> {
36 marker: PhantomData<fn() -> HashMap<K, V>>,
37}
38
39impl<'de, K, V> Visitor<'de> for SkipNullValuesMapVisitor<K, V>
40where
41 K: Deserialize<'de> + Eq + Hash,
42 V: Deserialize<'de>,
43{
44 type Value = HashMap<K, V>;
45
46 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
47 formatter.write_str("a very special map")
48 }
49
50 fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
51 where
52 M: MapAccess<'de>,
53 {
54 let mut map = HashMap::with_capacity(access.size_hint().unwrap_or(0));
55
56 while let Some((key, value)) = access.next_entry::<K, Option<V>>()? {
59 if let Some(value) = value {
60 map.insert(key, value);
61 }
62 }
63
64 Ok(map)
65 }
66}
67
68struct OptionSkipNullValuesMapVisitor<T> {
69 marker: PhantomData<T>,
70}
71
72impl<'de, K, V> Visitor<'de> for OptionSkipNullValuesMapVisitor<HashMap<K, V>>
73where
74 K: Deserialize<'de> + Eq + Hash,
75 V: Deserialize<'de>,
76{
77 type Value = Option<HashMap<K, V>>;
78
79 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
80 formatter.write_str("option")
81 }
82
83 #[inline]
84 fn visit_unit<E>(self) -> Result<Self::Value, E>
85 where
86 E: serde::de::Error,
87 {
88 Ok(None)
89 }
90
91 #[inline]
92 fn visit_none<E>(self) -> Result<Self::Value, E>
93 where
94 E: serde::de::Error,
95 {
96 Ok(None)
97 }
98
99 #[inline]
100 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
101 where
102 D: Deserializer<'de>,
103 {
104 deserialize_map_without_null_values(deserializer).map(Some)
105 }
106
107 #[doc(hidden)]
108 fn __private_visit_untagged_option<D>(self, deserializer: D) -> Result<Self::Value, ()>
109 where
110 D: Deserializer<'de>,
111 {
112 Ok(deserialize_map_without_null_values(deserializer).ok())
113 }
114}