Skip to main content

deser_core/foreign_impls/
hashbrown.rs

1//! `HashMap` and `HashSet` of `hashbrown`.
2//!
3//! They are serialized like the maps and sets of the standard library.
4use core::hash::{BuildHasher, Hash};
5
6use ::hashbrown::{HashMap, HashSet, hash_map};
7
8use crate::State;
9use crate::adapters::ser_impls::{serialize_as_map, serialize_as_set};
10use crate::adapters::{DeserializeAs, MapSkipError, Same, SerializeAs, skip_map_sink};
11use crate::de::impls::{
12    MapOut, MapTarget, SetTarget, collection_methods, collection_methods_as, map_sink,
13    set_collection, set_sink,
14};
15use crate::de::{Deserialize, SinkHandle};
16use crate::error::Error;
17use crate::event::ContainerShape;
18use crate::ser::impls::{serialize_map, serialize_set};
19use crate::ser::{Chunk, Describe};
20
21serialize_map! {
22    [K, V, S: Sync] HashMap<K, V, S> => Arbitrary;
23}
24
25serialize_as_map! {
26    [K, V, S: Sync, KA, VA] HashMap<K, V, S> => HashMap<KA, VA>, Arbitrary;
27}
28
29impl<K, V, S> MapTarget<K, V> for HashMap<K, V, S>
30where
31    K: Hash + Eq + Send,
32    V: Send,
33    S: BuildHasher + Default + Send,
34{
35    const NAME: &'static str = "HashMap";
36
37    #[inline]
38    fn insert_entry(&mut self, key: K, value: V, replace: bool) -> bool {
39        match self.entry(key) {
40            hash_map::Entry::Vacant(entry) => {
41                entry.insert(value);
42                false
43            }
44            hash_map::Entry::Occupied(mut entry) => {
45                if replace {
46                    entry.insert(value);
47                }
48                true
49            }
50        }
51    }
52
53    #[inline]
54    fn reserve_entries(&mut self, additional: usize) {
55        self.reserve(additional);
56    }
57
58    #[inline]
59    fn entry_mut(&mut self, key: &K) -> Option<&mut V> {
60        self.get_mut(key)
61    }
62
63    fn merge(&mut self, mut other: Self) {
64        // the smaller map is moved into the larger one
65        if other.len() > self.len() {
66            core::mem::swap(self, &mut other);
67            for (key, value) in other {
68                self.entry(key).or_insert(value);
69            }
70        } else {
71            self.extend(other);
72        }
73    }
74}
75
76impl<'de, K, V, S> Deserialize<'de> for HashMap<K, V, S>
77where
78    K: Hash + Eq + Deserialize<'de>,
79    V: Deserialize<'de>,
80    S: BuildHasher + Default + Send,
81{
82    #[inline]
83    fn deserialize_into<'out>(
84        out: &'out mut Option<Self>,
85        state: &mut State,
86    ) -> SinkHandle<'out, 'de> {
87        map_sink::<_, K, V, Same, Same>(MapOut::Slot(out), state)
88    }
89
90    /// Merges the entries into the map, the values of keys that exist are
91    /// replaced (not updated).
92    fn deserialize_update<'out>(value: &'out mut Self, state: &mut State) -> SinkHandle<'out, 'de> {
93        map_sink::<_, K, V, Same, Same>(MapOut::Update(value), state)
94    }
95}
96
97impl<'de, K, V, S, KA, VA> DeserializeAs<'de, HashMap<K, V, S>> for HashMap<KA, VA>
98where
99    K: Hash + Eq + Send,
100    V: Send,
101    S: BuildHasher + Default + Send,
102    KA: DeserializeAs<'de, K>,
103    VA: DeserializeAs<'de, V>,
104{
105    fn deserialize_into_as<'out>(
106        out: &'out mut Option<HashMap<K, V, S>>,
107        state: &mut State,
108    ) -> SinkHandle<'out, 'de> {
109        map_sink::<_, K, V, KA, VA>(MapOut::Slot(out), state)
110    }
111}
112
113impl<'de, K, V, S, KA, VA> DeserializeAs<'de, HashMap<K, V, S>> for MapSkipError<KA, VA>
114where
115    K: Hash + Eq + Send,
116    V: Send,
117    S: BuildHasher + Default + Send,
118    KA: DeserializeAs<'de, K>,
119    VA: DeserializeAs<'de, V>,
120{
121    fn deserialize_into_as<'out>(
122        out: &'out mut Option<HashMap<K, V, S>>,
123        state: &mut State,
124    ) -> SinkHandle<'out, 'de> {
125        skip_map_sink::<_, K, V, KA, VA>(out, state)
126    }
127}
128
129impl<K, V, S, KA, VA> SerializeAs<HashMap<K, V, S>> for MapSkipError<KA, VA>
130where
131    K: Sync,
132    V: Sync,
133    S: Sync,
134    KA: SerializeAs<K>,
135    VA: SerializeAs<V>,
136{
137    fn serialize_as<'a>(
138        value: &'a HashMap<K, V, S>,
139        state: &mut State,
140    ) -> Result<Chunk<'a>, Error> {
141        <HashMap<KA, VA> as SerializeAs<HashMap<K, V, S>>>::serialize_as(value, state)
142    }
143
144    fn container_shape_as(value: &HashMap<K, V, S>) -> ContainerShape {
145        <HashMap<KA, VA> as SerializeAs<HashMap<K, V, S>>>::container_shape_as(value)
146    }
147
148    fn describe_as(value: &HashMap<K, V, S>, d: &mut dyn Describe) {
149        <HashMap<KA, VA> as SerializeAs<HashMap<K, V, S>>>::describe_as(value, d)
150    }
151}
152
153serialize_set! {
154    [T, S: Sync] HashSet<T, S> => Arbitrary;
155}
156
157serialize_as_set! {
158    [T, S: Sync, A] HashSet<T, S> => HashSet<A>, Arbitrary;
159}
160
161impl<T, S> SetTarget<T> for HashSet<T, S>
162where
163    T: Hash + Eq + Send,
164    S: BuildHasher + Default + Send,
165{
166    const NAME: &'static str = "HashSet";
167
168    #[inline]
169    fn insert_element(&mut self, value: T) {
170        self.insert(value);
171    }
172
173    #[inline]
174    fn reserve_elements(&mut self, additional: usize) {
175        self.reserve(additional);
176    }
177}
178
179impl<'de, T, S> Deserialize<'de> for HashSet<T, S>
180where
181    T: Hash + Eq + Deserialize<'de>,
182    S: BuildHasher + Default + Send,
183{
184    #[inline]
185    fn deserialize_into<'out>(
186        out: &'out mut Option<Self>,
187        state: &mut State,
188    ) -> SinkHandle<'out, 'de> {
189        set_sink::<_, T, Same>(out, state)
190    }
191
192    collection_methods!(set Same);
193}
194
195set_collection! {
196    [T: Hash + Eq + Send, S: BuildHasher + Default + Send] HashSet<T, S>;
197}
198
199impl<'de, T, S, A> DeserializeAs<'de, HashSet<T, S>> for HashSet<A>
200where
201    T: Hash + Eq + Send,
202    S: BuildHasher + Default + Send,
203    A: DeserializeAs<'de, T>,
204{
205    fn deserialize_into_as<'out>(
206        out: &'out mut Option<HashSet<T, S>>,
207        state: &mut State,
208    ) -> SinkHandle<'out, 'de> {
209        set_sink::<_, T, A>(out, state)
210    }
211
212    collection_methods_as!(set HashSet<T, S>);
213}