Skip to main content

serde_with/duplicate_key_impls/
first_value_wins.rs

1use crate::prelude::*;
2#[cfg(any(
3    feature = "std",
4    feature = "hashbrown_0_14",
5    feature = "hashbrown_0_15",
6    feature = "hashbrown_0_16",
7    feature = "hashbrown_0_17",
8    feature = "indexmap_1",
9    feature = "indexmap_2"
10))]
11use crate::utils::size_hint_cautious;
12
13pub trait DuplicateInsertsFirstWinsMap<K, V> {
14    fn new(size_hint: Option<usize>) -> Self;
15
16    /// Insert the value into the map, if there is not already an existing value
17    fn insert(&mut self, key: K, value: V);
18}
19
20#[cfg(feature = "std")]
21impl<K, V, S> DuplicateInsertsFirstWinsMap<K, V> for HashMap<K, V, S>
22where
23    K: Eq + Hash,
24    S: BuildHasher + Default,
25{
26    #[inline]
27    fn new(size_hint: Option<usize>) -> Self {
28        Self::with_capacity_and_hasher(size_hint_cautious::<(K, V)>(size_hint), S::default())
29    }
30
31    #[inline]
32    fn insert(&mut self, key: K, value: V) {
33        use std::collections::hash_map::Entry;
34
35        match self.entry(key) {
36            // we want to keep the first value, so do nothing
37            Entry::Occupied(_) => {}
38            Entry::Vacant(vacant) => {
39                vacant.insert(value);
40            }
41        }
42    }
43}
44
45#[cfg(feature = "hashbrown_0_14")]
46impl<K, V, S> DuplicateInsertsFirstWinsMap<K, V> for hashbrown_0_14::HashMap<K, V, S>
47where
48    K: Eq + Hash,
49    S: BuildHasher + Default,
50{
51    #[inline]
52    fn new(size_hint: Option<usize>) -> Self {
53        Self::with_capacity_and_hasher(size_hint_cautious::<(K, V)>(size_hint), S::default())
54    }
55
56    #[inline]
57    fn insert(&mut self, key: K, value: V) {
58        use hashbrown_0_14::hash_map::Entry;
59
60        match self.entry(key) {
61            // we want to keep the first value, so do nothing
62            Entry::Occupied(_) => {}
63            Entry::Vacant(vacant) => {
64                vacant.insert(value);
65            }
66        }
67    }
68}
69
70#[cfg(feature = "hashbrown_0_15")]
71impl<K, V, S> DuplicateInsertsFirstWinsMap<K, V> for hashbrown_0_15::HashMap<K, V, S>
72where
73    K: Eq + Hash,
74    S: BuildHasher + Default,
75{
76    #[inline]
77    fn new(size_hint: Option<usize>) -> Self {
78        Self::with_capacity_and_hasher(size_hint_cautious::<(K, V)>(size_hint), S::default())
79    }
80
81    #[inline]
82    fn insert(&mut self, key: K, value: V) {
83        use hashbrown_0_15::hash_map::Entry;
84
85        match self.entry(key) {
86            // we want to keep the first value, so do nothing
87            Entry::Occupied(_) => {}
88            Entry::Vacant(vacant) => {
89                vacant.insert(value);
90            }
91        }
92    }
93}
94
95#[cfg(feature = "hashbrown_0_16")]
96impl<K, V, S> DuplicateInsertsFirstWinsMap<K, V> for hashbrown_0_16::HashMap<K, V, S>
97where
98    K: Eq + Hash,
99    S: BuildHasher + Default,
100{
101    #[inline]
102    fn new(size_hint: Option<usize>) -> Self {
103        Self::with_capacity_and_hasher(size_hint_cautious::<(K, V)>(size_hint), S::default())
104    }
105
106    #[inline]
107    fn insert(&mut self, key: K, value: V) {
108        use hashbrown_0_16::hash_map::Entry;
109
110        match self.entry(key) {
111            // we want to keep the first value, so do nothing
112            Entry::Occupied(_) => {}
113            Entry::Vacant(vacant) => {
114                vacant.insert(value);
115            }
116        }
117    }
118}
119
120#[cfg(feature = "hashbrown_0_17")]
121impl<K, V, S> DuplicateInsertsFirstWinsMap<K, V> for hashbrown_0_17::HashMap<K, V, S>
122where
123    K: Eq + Hash,
124    S: BuildHasher + Default,
125{
126    #[inline]
127    fn new(size_hint: Option<usize>) -> Self {
128        Self::with_capacity_and_hasher(size_hint_cautious::<(K, V)>(size_hint), S::default())
129    }
130
131    #[inline]
132    fn insert(&mut self, key: K, value: V) {
133        use hashbrown_0_17::hash_map::Entry;
134
135        match self.entry(key) {
136            // we want to keep the first value, so do nothing
137            Entry::Occupied(_) => {}
138            Entry::Vacant(vacant) => {
139                vacant.insert(value);
140            }
141        }
142    }
143}
144
145#[cfg(feature = "indexmap_1")]
146impl<K, V, S> DuplicateInsertsFirstWinsMap<K, V> for indexmap_1::IndexMap<K, V, S>
147where
148    K: Eq + Hash,
149    S: BuildHasher + Default,
150{
151    #[inline]
152    fn new(size_hint: Option<usize>) -> Self {
153        Self::with_capacity_and_hasher(size_hint_cautious::<(K, V)>(size_hint), S::default())
154    }
155
156    #[inline]
157    fn insert(&mut self, key: K, value: V) {
158        use indexmap_1::map::Entry;
159
160        match self.entry(key) {
161            // we want to keep the first value, so do nothing
162            Entry::Occupied(_) => {}
163            Entry::Vacant(vacant) => {
164                vacant.insert(value);
165            }
166        }
167    }
168}
169
170#[cfg(feature = "indexmap_2")]
171impl<K, V, S> DuplicateInsertsFirstWinsMap<K, V> for indexmap_2::IndexMap<K, V, S>
172where
173    K: Eq + Hash,
174    S: BuildHasher + Default,
175{
176    #[inline]
177    fn new(size_hint: Option<usize>) -> Self {
178        Self::with_capacity_and_hasher(size_hint_cautious::<(K, V)>(size_hint), S::default())
179    }
180
181    #[inline]
182    fn insert(&mut self, key: K, value: V) {
183        use indexmap_2::map::Entry;
184
185        match self.entry(key) {
186            // we want to keep the first value, so do nothing
187            Entry::Occupied(_) => {}
188            Entry::Vacant(vacant) => {
189                vacant.insert(value);
190            }
191        }
192    }
193}
194
195impl<K, V> DuplicateInsertsFirstWinsMap<K, V> for BTreeMap<K, V>
196where
197    K: Ord,
198{
199    #[inline]
200    fn new(_size_hint: Option<usize>) -> Self {
201        Self::new()
202    }
203
204    #[inline]
205    fn insert(&mut self, key: K, value: V) {
206        use alloc::collections::btree_map::Entry;
207
208        match self.entry(key) {
209            // we want to keep the first value, so do nothing
210            Entry::Occupied(_) => {}
211            Entry::Vacant(vacant) => {
212                vacant.insert(value);
213            }
214        }
215    }
216}