/rust/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-2.14.0/src/map/entry.rs
Line | Count | Source |
1 | | use crate::Bucket; |
2 | | use crate::inner::{Core, OccupiedEntry, VacantEntry}; |
3 | | use core::{fmt, mem}; |
4 | | |
5 | | /// Entry for an existing key-value pair in an [`IndexMap`][crate::IndexMap] |
6 | | /// or a vacant location to insert one. |
7 | | pub enum Entry<'a, K, V> { |
8 | | /// Existing slot with equivalent key. |
9 | | Occupied(OccupiedEntry<'a, K, V>), |
10 | | /// Vacant slot (no equivalent key in the map). |
11 | | Vacant(VacantEntry<'a, K, V>), |
12 | | } |
13 | | |
14 | | impl<'a, K, V> Entry<'a, K, V> { |
15 | | /// Return the index where the key-value pair exists or will be inserted. |
16 | | pub fn index(&self) -> usize { |
17 | | match self { |
18 | | Entry::Occupied(entry) => entry.index(), |
19 | | Entry::Vacant(entry) => entry.index(), |
20 | | } |
21 | | } |
22 | | |
23 | | /// Sets the value of the entry (after inserting if vacant), and returns an `OccupiedEntry`. |
24 | | /// |
25 | | /// Computes in **O(1)** time (amortized average). |
26 | | pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> { |
27 | | match self { |
28 | | Entry::Occupied(mut entry) => { |
29 | | entry.insert(value); |
30 | | entry |
31 | | } |
32 | | Entry::Vacant(entry) => entry.insert_entry(value), |
33 | | } |
34 | | } |
35 | | |
36 | | /// Inserts the given default value in the entry if it is vacant and returns a mutable |
37 | | /// reference to it. Otherwise a mutable reference to an already existent value is returned. |
38 | | /// |
39 | | /// Computes in **O(1)** time (amortized average). |
40 | 0 | pub fn or_insert(self, default: V) -> &'a mut V { |
41 | 0 | match self { |
42 | 0 | Entry::Occupied(entry) => entry.into_mut(), |
43 | 0 | Entry::Vacant(entry) => entry.insert(default), |
44 | | } |
45 | 0 | } |
46 | | |
47 | | /// Inserts the result of the `call` function in the entry if it is vacant and returns a mutable |
48 | | /// reference to it. Otherwise a mutable reference to an already existent value is returned. |
49 | | /// |
50 | | /// Computes in **O(1)** time (amortized average). |
51 | | pub fn or_insert_with<F>(self, call: F) -> &'a mut V |
52 | | where |
53 | | F: FnOnce() -> V, |
54 | | { |
55 | | match self { |
56 | | Entry::Occupied(entry) => entry.into_mut(), |
57 | | Entry::Vacant(entry) => entry.insert(call()), |
58 | | } |
59 | | } |
60 | | |
61 | | /// Inserts the result of the `call` function with a reference to the entry's key if it is |
62 | | /// vacant, and returns a mutable reference to the new value. Otherwise a mutable reference to |
63 | | /// an already existent value is returned. |
64 | | /// |
65 | | /// Computes in **O(1)** time (amortized average). |
66 | | pub fn or_insert_with_key<F>(self, call: F) -> &'a mut V |
67 | | where |
68 | | F: FnOnce(&K) -> V, |
69 | | { |
70 | | match self { |
71 | | Entry::Occupied(entry) => entry.into_mut(), |
72 | | Entry::Vacant(entry) => { |
73 | | let value = call(entry.key()); |
74 | | entry.insert(value) |
75 | | } |
76 | | } |
77 | | } |
78 | | |
79 | | /// Gets a reference to the entry's key, either within the map if occupied, |
80 | | /// or else the new key that was used to find the entry. |
81 | | pub fn key(&self) -> &K { |
82 | | match *self { |
83 | | Entry::Occupied(ref entry) => entry.key(), |
84 | | Entry::Vacant(ref entry) => entry.key(), |
85 | | } |
86 | | } |
87 | | |
88 | | /// Modifies the entry if it is occupied. |
89 | | pub fn and_modify<F>(mut self, f: F) -> Self |
90 | | where |
91 | | F: FnOnce(&mut V), |
92 | | { |
93 | | if let Entry::Occupied(entry) = &mut self { |
94 | | f(entry.get_mut()); |
95 | | } |
96 | | self |
97 | | } |
98 | | |
99 | | /// Inserts a default-constructed value in the entry if it is vacant and returns a mutable |
100 | | /// reference to it. Otherwise a mutable reference to an already existent value is returned. |
101 | | /// |
102 | | /// Computes in **O(1)** time (amortized average). |
103 | | pub fn or_default(self) -> &'a mut V |
104 | | where |
105 | | V: Default, |
106 | | { |
107 | | match self { |
108 | | Entry::Occupied(entry) => entry.into_mut(), |
109 | | Entry::Vacant(entry) => entry.insert(V::default()), |
110 | | } |
111 | | } |
112 | | } |
113 | | |
114 | | impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Entry<'_, K, V> { |
115 | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
116 | | let mut tuple = f.debug_tuple("Entry"); |
117 | | match self { |
118 | | Entry::Vacant(v) => tuple.field(v), |
119 | | Entry::Occupied(o) => tuple.field(o), |
120 | | }; |
121 | | tuple.finish() |
122 | | } |
123 | | } |
124 | | |
125 | | impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for OccupiedEntry<'_, K, V> { |
126 | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
127 | | f.debug_struct("OccupiedEntry") |
128 | | .field("key", self.key()) |
129 | | .field("value", self.get()) |
130 | | .finish() |
131 | | } |
132 | | } |
133 | | |
134 | | impl<K: fmt::Debug, V> fmt::Debug for VacantEntry<'_, K, V> { |
135 | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
136 | | f.debug_tuple("VacantEntry").field(self.key()).finish() |
137 | | } |
138 | | } |
139 | | |
140 | | /// A view into an occupied entry in an [`IndexMap`][crate::IndexMap] obtained by index. |
141 | | /// |
142 | | /// This `struct` is created from the [`get_index_entry`][crate::IndexMap::get_index_entry] method. |
143 | | pub struct IndexedEntry<'a, K, V> { |
144 | | map: &'a mut Core<K, V>, |
145 | | // We have a mutable reference to the map, which keeps the index |
146 | | // valid and pointing to the correct entry. |
147 | | index: usize, |
148 | | } |
149 | | |
150 | | impl<'a, K, V> IndexedEntry<'a, K, V> { |
151 | | pub(crate) fn new(map: &'a mut Core<K, V>, index: usize) -> Option<Self> { |
152 | | if index < map.len() { |
153 | | Some(Self { map, index }) |
154 | | } else { |
155 | | None |
156 | | } |
157 | | } |
158 | | |
159 | | /// Return the index of the key-value pair |
160 | | #[inline] |
161 | | pub fn index(&self) -> usize { |
162 | | self.index |
163 | | } |
164 | | |
165 | | pub(crate) fn into_core(self) -> &'a mut Core<K, V> { |
166 | | self.map |
167 | | } |
168 | | |
169 | | fn get_bucket(&self) -> &Bucket<K, V> { |
170 | | &self.map.as_entries()[self.index] |
171 | | } |
172 | | |
173 | | fn get_bucket_mut(&mut self) -> &mut Bucket<K, V> { |
174 | | &mut self.map.as_entries_mut()[self.index] |
175 | | } |
176 | | |
177 | | fn into_bucket(self) -> &'a mut Bucket<K, V> { |
178 | | &mut self.map.as_entries_mut()[self.index] |
179 | | } |
180 | | |
181 | | /// Gets a reference to the entry's key in the map. |
182 | | pub fn key(&self) -> &K { |
183 | | &self.get_bucket().key |
184 | | } |
185 | | |
186 | | pub(super) fn key_mut(&mut self) -> &mut K { |
187 | | &mut self.get_bucket_mut().key |
188 | | } |
189 | | |
190 | | /// Gets a reference to the entry's value in the map. |
191 | | pub fn get(&self) -> &V { |
192 | | &self.get_bucket().value |
193 | | } |
194 | | |
195 | | /// Gets a mutable reference to the entry's value in the map. |
196 | | /// |
197 | | /// If you need a reference which may outlive the destruction of the |
198 | | /// `IndexedEntry` value, see [`into_mut`][Self::into_mut]. |
199 | | pub fn get_mut(&mut self) -> &mut V { |
200 | | &mut self.get_bucket_mut().value |
201 | | } |
202 | | |
203 | | /// Sets the value of the entry to `value`, and returns the entry's old value. |
204 | | pub fn insert(&mut self, value: V) -> V { |
205 | | mem::replace(self.get_mut(), value) |
206 | | } |
207 | | |
208 | | /// Converts into a mutable reference to the entry's value in the map, |
209 | | /// with a lifetime bound to the map itself. |
210 | | pub fn into_mut(self) -> &'a mut V { |
211 | | &mut self.into_bucket().value |
212 | | } |
213 | | |
214 | | /// Remove and return the key, value pair stored in the map for this entry |
215 | | /// |
216 | | /// Like [`Vec::swap_remove`][alloc::vec::Vec::swap_remove], the pair is removed by swapping it |
217 | | /// with the last element of the map and popping it off. |
218 | | /// **This perturbs the position of what used to be the last element!** |
219 | | /// |
220 | | /// Computes in **O(1)** time (average). |
221 | | pub fn swap_remove_entry(self) -> (K, V) { |
222 | | self.map.swap_remove_index(self.index).unwrap() |
223 | | } |
224 | | |
225 | | /// Remove and return the key, value pair stored in the map for this entry |
226 | | /// |
227 | | /// Like [`Vec::remove`][alloc::vec::Vec::remove], the pair is removed by shifting all of the |
228 | | /// elements that follow it, preserving their relative order. |
229 | | /// **This perturbs the index of all of those elements!** |
230 | | /// |
231 | | /// Computes in **O(n)** time (average). |
232 | | pub fn shift_remove_entry(self) -> (K, V) { |
233 | | self.map.shift_remove_index(self.index).unwrap() |
234 | | } |
235 | | |
236 | | /// Remove the key, value pair stored in the map for this entry, and return the value. |
237 | | /// |
238 | | /// Like [`Vec::swap_remove`][alloc::vec::Vec::swap_remove], the pair is removed by swapping it |
239 | | /// with the last element of the map and popping it off. |
240 | | /// **This perturbs the position of what used to be the last element!** |
241 | | /// |
242 | | /// Computes in **O(1)** time (average). |
243 | | pub fn swap_remove(self) -> V { |
244 | | self.swap_remove_entry().1 |
245 | | } |
246 | | |
247 | | /// Remove the key, value pair stored in the map for this entry, and return the value. |
248 | | /// |
249 | | /// Like [`Vec::remove`][alloc::vec::Vec::remove], the pair is removed by shifting all of the |
250 | | /// elements that follow it, preserving their relative order. |
251 | | /// **This perturbs the index of all of those elements!** |
252 | | /// |
253 | | /// Computes in **O(n)** time (average). |
254 | | pub fn shift_remove(self) -> V { |
255 | | self.shift_remove_entry().1 |
256 | | } |
257 | | |
258 | | /// Moves the position of the entry to a new index |
259 | | /// by shifting all other entries in-between. |
260 | | /// |
261 | | /// This is equivalent to [`IndexMap::move_index`][`crate::IndexMap::move_index`] |
262 | | /// coming `from` the current [`.index()`][Self::index]. |
263 | | /// |
264 | | /// * If `self.index() < to`, the other pairs will shift down while the targeted pair moves up. |
265 | | /// * If `self.index() > to`, the other pairs will shift up while the targeted pair moves down. |
266 | | /// |
267 | | /// ***Panics*** if `to` is out of bounds. |
268 | | /// |
269 | | /// Computes in **O(n)** time (average). |
270 | | #[track_caller] |
271 | | pub fn move_index(self, to: usize) { |
272 | | self.map.move_index(self.index, to); |
273 | | } |
274 | | |
275 | | /// Swaps the position of entry with another. |
276 | | /// |
277 | | /// This is equivalent to [`IndexMap::swap_indices`][`crate::IndexMap::swap_indices`] |
278 | | /// with the current [`.index()`][Self::index] as one of the two being swapped. |
279 | | /// |
280 | | /// ***Panics*** if the `other` index is out of bounds. |
281 | | /// |
282 | | /// Computes in **O(1)** time (average). |
283 | | #[track_caller] |
284 | | pub fn swap_indices(self, other: usize) { |
285 | | self.map.swap_indices(self.index, other); |
286 | | } |
287 | | } |
288 | | |
289 | | impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IndexedEntry<'_, K, V> { |
290 | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
291 | | f.debug_struct("IndexedEntry") |
292 | | .field("index", &self.index) |
293 | | .field("key", self.key()) |
294 | | .field("value", self.get()) |
295 | | .finish() |
296 | | } |
297 | | } |
298 | | |
299 | | impl<'a, K, V> From<OccupiedEntry<'a, K, V>> for IndexedEntry<'a, K, V> { |
300 | | fn from(other: OccupiedEntry<'a, K, V>) -> Self { |
301 | | Self { |
302 | | index: other.index(), |
303 | | map: other.into_core(), |
304 | | } |
305 | | } |
306 | | } |
307 | | |
308 | | #[test] |
309 | | fn assert_send_sync() { |
310 | | fn assert_send_sync<T: Send + Sync>() {} |
311 | | assert_send_sync::<Entry<'_, i32, i32>>(); |
312 | | assert_send_sync::<IndexedEntry<'_, i32, i32>>(); |
313 | | } |