rune_alloc/hashbrown/
serde.rs

1mod size_hint {
2    use core::cmp;
3
4    /// This presumably exists to prevent denial of service attacks.
5    ///
6    /// Original discussion: https://github.com/serde-rs/serde/issues/1114.
7    #[cfg_attr(feature = "inline-more", inline)]
8    pub(super) fn cautious(hint: Option<usize>) -> usize {
9        cmp::min(hint.unwrap_or(0), 4096)
10    }
11}
12
13mod map {
14    use crate::alloc::Allocator;
15
16    use core::fmt;
17    use core::hash::{BuildHasher, Hash};
18    use core::marker::PhantomData;
19
20    use serde::de::{Deserialize, Deserializer, Error, MapAccess, Visitor};
21    use serde::ser::{Serialize, Serializer};
22
23    use crate::hash_map::HashMap;
24
25    use super::size_hint;
26
27    impl<K, V, H, A> Serialize for HashMap<K, V, H, A>
28    where
29        K: Serialize + Eq + Hash,
30        V: Serialize,
31        H: BuildHasher,
32        A: Allocator,
33    {
34        #[cfg_attr(feature = "inline-more", inline)]
35        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
36        where
37            S: Serializer,
38        {
39            serializer.collect_map(self)
40        }
41    }
42
43    impl<'de, K, V, S, A> Deserialize<'de> for HashMap<K, V, S, A>
44    where
45        K: Deserialize<'de> + Eq + Hash,
46        V: Deserialize<'de>,
47        S: BuildHasher + Default,
48        A: Allocator + Default,
49    {
50        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
51        where
52            D: Deserializer<'de>,
53        {
54            struct MapVisitor<K, V, S, A>
55            where
56                A: Allocator,
57            {
58                marker: PhantomData<HashMap<K, V, S, A>>,
59            }
60
61            impl<'de, K, V, S, A> Visitor<'de> for MapVisitor<K, V, S, A>
62            where
63                K: Deserialize<'de> + Eq + Hash,
64                V: Deserialize<'de>,
65                S: BuildHasher + Default,
66                A: Allocator + Default,
67            {
68                type Value = HashMap<K, V, S, A>;
69
70                fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
71                    formatter.write_str("a map")
72                }
73
74                #[cfg_attr(feature = "inline-more", inline)]
75                fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
76                where
77                    M: MapAccess<'de>,
78                {
79                    let mut values = HashMap::try_with_capacity_and_hasher_in(
80                        size_hint::cautious(map.size_hint()),
81                        S::default(),
82                        A::default(),
83                    )
84                    .map_err(M::Error::custom)?;
85
86                    while let Some((key, value)) = map.next_entry()? {
87                        values.try_insert(key, value).map_err(M::Error::custom)?;
88                    }
89
90                    Ok(values)
91                }
92            }
93
94            let visitor = MapVisitor {
95                marker: PhantomData,
96            };
97            deserializer.deserialize_map(visitor)
98        }
99    }
100}
101
102mod set {
103    use crate::alloc::Allocator;
104
105    use core::fmt;
106    use core::hash::{BuildHasher, Hash};
107    use core::marker::PhantomData;
108    use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor};
109    use serde::ser::{Serialize, Serializer};
110
111    use crate::hash_set::HashSet;
112
113    use super::size_hint;
114
115    impl<T, H, A> Serialize for HashSet<T, H, A>
116    where
117        T: Serialize + Eq + Hash,
118        H: BuildHasher,
119        A: Allocator,
120    {
121        #[cfg_attr(feature = "inline-more", inline)]
122        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
123        where
124            S: Serializer,
125        {
126            serializer.collect_seq(self)
127        }
128    }
129
130    impl<'de, T, S, A> Deserialize<'de> for HashSet<T, S, A>
131    where
132        T: Deserialize<'de> + Eq + Hash,
133        S: BuildHasher + Default,
134        A: Allocator + Default,
135    {
136        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
137        where
138            D: Deserializer<'de>,
139        {
140            struct SeqVisitor<T, S, A>
141            where
142                A: Allocator,
143            {
144                marker: PhantomData<HashSet<T, S, A>>,
145            }
146
147            impl<'de, T, S, A> Visitor<'de> for SeqVisitor<T, S, A>
148            where
149                T: Deserialize<'de> + Eq + Hash,
150                S: BuildHasher + Default,
151                A: Allocator + Default,
152            {
153                type Value = HashSet<T, S, A>;
154
155                fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
156                    formatter.write_str("a sequence")
157                }
158
159                #[cfg_attr(feature = "inline-more", inline)]
160                fn visit_seq<M>(self, mut seq: M) -> Result<Self::Value, M::Error>
161                where
162                    M: SeqAccess<'de>,
163                {
164                    let mut values = HashSet::try_with_capacity_and_hasher_in(
165                        size_hint::cautious(seq.size_hint()),
166                        S::default(),
167                        A::default(),
168                    )
169                    .map_err(M::Error::custom)?;
170
171                    while let Some(value) = seq.next_element()? {
172                        values.try_insert(value).map_err(M::Error::custom)?;
173                    }
174
175                    Ok(values)
176                }
177            }
178
179            let visitor = SeqVisitor {
180                marker: PhantomData,
181            };
182            deserializer.deserialize_seq(visitor)
183        }
184
185        #[allow(clippy::missing_errors_doc)]
186        fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
187        where
188            D: Deserializer<'de>,
189        {
190            struct SeqInPlaceVisitor<'a, T, S, A>(&'a mut HashSet<T, S, A>)
191            where
192                A: Allocator;
193
194            impl<'de, T, S, A> Visitor<'de> for SeqInPlaceVisitor<'_, T, S, A>
195            where
196                T: Deserialize<'de> + Eq + Hash,
197                S: BuildHasher + Default,
198                A: Allocator,
199            {
200                type Value = ();
201
202                fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
203                    formatter.write_str("a sequence")
204                }
205
206                #[cfg_attr(feature = "inline-more", inline)]
207                fn visit_seq<M>(self, mut seq: M) -> Result<Self::Value, M::Error>
208                where
209                    M: SeqAccess<'de>,
210                {
211                    self.0.clear();
212                    self.0
213                        .try_reserve(size_hint::cautious(seq.size_hint()))
214                        .map_err(M::Error::custom)?;
215
216                    while let Some(value) = seq.next_element()? {
217                        self.0.try_insert(value).map_err(M::Error::custom)?;
218                    }
219
220                    Ok(())
221                }
222            }
223
224            deserializer.deserialize_seq(SeqInPlaceVisitor(place))
225        }
226    }
227}