Skip to main content

deser_core/foreign_impls/
indexmap.rs

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