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//! Written as adapters (like `IndexMap<KA, VA>`), the hasher is not used.
8use core::hash::{BuildHasher, Hash};
9
10use ::indexmap::{IndexMap, IndexSet, map};
11
12use alloc::borrow::Cow;
13
14use crate::State;
15use crate::adapters::{MapSkipError, skip_map_sink};
16use crate::de::impls::{
17    MapOut, MapTarget, SetTarget, collection_methods, map_sink, set_collection, set_sink,
18};
19use crate::de::{Deserialize, SinkHandle};
20use crate::error::Error;
21use crate::event::ContainerShape;
22use crate::ser::impls::{serialize_map, serialize_set};
23use crate::ser::{Describe, Emit, Serialize};
24
25// the hasher of the adapter is not used
26serialize_map! {
27    [K, V, S: Sync, KA, VA, AS: Sync] IndexMap<K, V, S> => IndexMap<KA, VA, AS>, Natural;
28}
29
30impl<K, V, S, KA, VA> Serialize<IndexMap<K, V, S>> for MapSkipError<KA, VA>
31where
32    K: Sync,
33    V: Sync,
34    S: Sync,
35    KA: Serialize<K>,
36    VA: Serialize<V>,
37{
38    fn serialize<'a>(value: &'a IndexMap<K, V, S>, state: &mut State) -> Result<Emit<'a>, Error> {
39        <IndexMap<KA, VA, S> as Serialize<IndexMap<K, V, S>>>::serialize(value, state)
40    }
41
42    fn container_shape(value: &IndexMap<K, V, S>) -> ContainerShape {
43        <IndexMap<KA, VA, S> as Serialize<IndexMap<K, V, S>>>::container_shape(value)
44    }
45
46    fn describe(value: &IndexMap<K, V, S>, d: &mut dyn Describe) {
47        <IndexMap<KA, VA, S> as Serialize<IndexMap<K, V, S>>>::describe(value, d)
48    }
49}
50
51impl<K, V, S> MapTarget<K, V> for IndexMap<K, V, S>
52where
53    K: Hash + Eq + Send,
54    V: Send,
55    S: BuildHasher + Default + Send,
56{
57    const NAME: &'static str = "IndexMap";
58
59    #[inline]
60    fn insert_entry(&mut self, key: K, value: V, replace: bool) -> bool {
61        match self.entry(key) {
62            map::Entry::Vacant(entry) => {
63                entry.insert(value);
64                false
65            }
66            map::Entry::Occupied(mut entry) => {
67                if replace {
68                    entry.insert(value);
69                }
70                true
71            }
72        }
73    }
74
75    #[inline]
76    fn reserve_entries(&mut self, additional: usize) {
77        self.reserve(additional);
78    }
79
80    #[inline]
81    fn entry_mut(&mut self, key: &K) -> Option<&mut V> {
82        self.get_mut(key)
83    }
84
85    fn merge(&mut self, other: Self) {
86        if self.is_empty() {
87            *self = other;
88        } else {
89            // existing keys keep their position, new ones are appended
90            self.extend(other);
91        }
92    }
93}
94
95// the hasher of the adapter is not used
96impl<'de, K, V, S, KA, VA, AS> Deserialize<'de, IndexMap<K, V, S>> for IndexMap<KA, VA, AS>
97where
98    K: Hash + Eq + Send,
99    V: Send,
100    S: BuildHasher + Default + Send,
101    KA: Deserialize<'de, K>,
102    VA: Deserialize<'de, V>,
103    AS: Send,
104{
105    #[inline]
106    fn deserialize_into<'out>(
107        out: &'out mut Option<IndexMap<K, V, S>>,
108        state: &mut State,
109    ) -> SinkHandle<'out, 'de> {
110        map_sink::<_, K, V, KA, VA>(MapOut::Slot(out), state)
111    }
112
113    fn expecting() -> Cow<'static, str> {
114        Cow::Borrowed(<IndexMap<K, V, S> as MapTarget<K, V>>::NAME)
115    }
116
117    /// Merges the entries into the map, the values of keys that exist are
118    /// replaced (not updated).  New keys are appended.
119    fn deserialize_update<'out>(
120        value: &'out mut IndexMap<K, V, S>,
121        state: &mut State,
122    ) -> SinkHandle<'out, 'de> {
123        map_sink::<_, K, V, KA, VA>(MapOut::Update(value), state)
124    }
125}
126
127impl<'de, K, V, S, KA, VA> Deserialize<'de, IndexMap<K, V, S>> for MapSkipError<KA, VA>
128where
129    K: Hash + Eq + Send,
130    V: Send,
131    S: BuildHasher + Default + Send,
132    KA: Deserialize<'de, K>,
133    VA: Deserialize<'de, V>,
134{
135    fn deserialize_into<'out>(
136        out: &'out mut Option<IndexMap<K, V, S>>,
137        state: &mut State,
138    ) -> SinkHandle<'out, 'de> {
139        skip_map_sink::<_, K, V, KA, VA>(out, state)
140    }
141
142    fn expecting() -> Cow<'static, str> {
143        Cow::Borrowed(<IndexMap<K, V, S> as MapTarget<K, V>>::NAME)
144    }
145}
146
147// the hasher of the adapter is not used
148serialize_set! {
149    [T, S: Sync, A, AS: Sync] IndexSet<T, S> => IndexSet<A, AS>, Natural;
150}
151
152impl<T, S> SetTarget<T> for IndexSet<T, S>
153where
154    T: Hash + Eq + Send,
155    S: BuildHasher + Default + Send,
156{
157    const NAME: &'static str = "IndexSet";
158
159    #[inline]
160    fn insert_element(&mut self, value: T) {
161        self.insert(value);
162    }
163
164    #[inline]
165    fn reserve_elements(&mut self, additional: usize) {
166        self.reserve(additional);
167    }
168}
169
170// the hasher of the adapter is not used
171impl<'de, T, S, A, AS> Deserialize<'de, IndexSet<T, S>> for IndexSet<A, AS>
172where
173    T: Hash + Eq + Send,
174    S: BuildHasher + Default + Send,
175    A: Deserialize<'de, T>,
176    AS: Send,
177{
178    #[inline]
179    fn deserialize_into<'out>(
180        out: &'out mut Option<IndexSet<T, S>>,
181        state: &mut State,
182    ) -> SinkHandle<'out, 'de> {
183        set_sink::<_, T, A>(out, state)
184    }
185
186    fn expecting() -> Cow<'static, str> {
187        Cow::Borrowed(<IndexSet<T, S> as SetTarget<T>>::NAME)
188    }
189
190    collection_methods!(set IndexSet<T, S>);
191}
192
193set_collection! {
194    [T: Hash + Eq + Send, S: BuildHasher + Default + Send] IndexSet<T, S>;
195}