vecmap/map/entry.rs
1use super::VecMap;
2use core::mem;
3
4/// Entry for an existing key-value pair or a vacant location to insert one.
5#[derive(Debug)]
6pub enum Entry<'a, K, V> {
7 /// Existing slot with equivalent key.
8 Occupied(OccupiedEntry<'a, K, V>),
9 /// Vacant slot (no equivalent key in the map).
10 Vacant(VacantEntry<'a, K, V>),
11}
12
13impl<'a, K, V> Entry<'a, K, V> {
14 /// Ensures a value is in the entry by inserting the default if empty, and returns a mutable
15 /// reference to the value in the entry.
16 ///
17 /// # Examples
18 ///
19 /// ```
20 /// use vecmap::VecMap;
21 ///
22 /// let mut map: VecMap<&str, u32> = VecMap::new();
23 ///
24 /// map.entry("poneyland").or_insert(3);
25 /// assert_eq!(map["poneyland"], 3);
26 ///
27 /// *map.entry("poneyland").or_insert(10) *= 2;
28 /// assert_eq!(map["poneyland"], 6);
29 /// ```
30 pub fn or_insert(self, default: V) -> &'a mut V {
31 match self {
32 Entry::Occupied(entry) => entry.into_mut(),
33 Entry::Vacant(entry) => entry.insert(default),
34 }
35 }
36
37 /// Ensures a value is in the entry by inserting the result of the default function if empty,
38 /// and returns a mutable reference to the value in the entry.
39 ///
40 /// # Examples
41 ///
42 /// ```
43 /// use vecmap::VecMap;
44 ///
45 /// let mut map: VecMap<&str, String> = VecMap::new();
46 /// let s = "hoho".to_string();
47 ///
48 /// map.entry("poneyland").or_insert_with(|| s);
49 ///
50 /// assert_eq!(map["poneyland"], "hoho".to_string());
51 /// ```
52 pub fn or_insert_with<F>(self, call: F) -> &'a mut V
53 where
54 F: FnOnce() -> V,
55 {
56 match self {
57 Entry::Occupied(entry) => entry.into_mut(),
58 Entry::Vacant(entry) => entry.insert(call()),
59 }
60 }
61
62 /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
63 /// This method allows for generating key-derived values for insertion by providing the default
64 /// function a reference to the key that was moved during the `.entry(key)` method call.
65 ///
66 /// The reference to the moved key is provided so that cloning or copying the key is
67 /// unnecessary, unlike with `.or_insert_with(|| ... )`.
68 ///
69 /// # Examples
70 ///
71 /// ```
72 /// use vecmap::VecMap;
73 ///
74 /// let mut map: VecMap<&str, usize> = VecMap::new();
75 ///
76 /// map.entry("poneyland").or_insert_with_key(|key| key.chars().count());
77 ///
78 /// assert_eq!(map["poneyland"], 9);
79 /// ```
80 pub fn or_insert_with_key<F>(self, default: F) -> &'a mut V
81 where
82 F: FnOnce(&K) -> V,
83 {
84 match self {
85 Entry::Occupied(entry) => entry.into_mut(),
86 Entry::Vacant(entry) => {
87 let value = default(&entry.key);
88 entry.insert(value)
89 }
90 }
91 }
92
93 /// Returns a reference to this entry's key.
94 ///
95 /// # Examples
96 ///
97 /// ```
98 /// use vecmap::VecMap;
99 ///
100 /// let mut map: VecMap<&str, u32> = VecMap::new();
101 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
102 /// ```
103 pub fn key(&self) -> &K {
104 match self {
105 Entry::Occupied(entry) => entry.key(),
106 Entry::Vacant(entry) => entry.key(),
107 }
108 }
109
110 /// Returns the index where the key-value pair exists or will be inserted.
111 ///
112 /// # Examples
113 ///
114 /// ```
115 /// use vecmap::VecMap;
116 ///
117 /// let mut map: VecMap<&str, u32> = VecMap::new();
118 /// assert_eq!(map.entry("poneyland").index(), 0);
119 /// ```
120 pub fn index(&self) -> usize {
121 match self {
122 Entry::Occupied(entry) => entry.index(),
123 Entry::Vacant(entry) => entry.index(),
124 }
125 }
126
127 /// Provides in-place mutable access to an occupied entry before any potential inserts into the
128 /// map.
129 ///
130 /// # Examples
131 ///
132 /// ```
133 /// use vecmap::VecMap;
134 ///
135 /// let mut map: VecMap<&str, u32> = VecMap::new();
136 ///
137 /// map.entry("poneyland")
138 /// .and_modify(|e| { *e += 1 })
139 /// .or_insert(42);
140 /// assert_eq!(map["poneyland"], 42);
141 ///
142 /// map.entry("poneyland")
143 /// .and_modify(|e| { *e += 1 })
144 /// .or_insert(42);
145 /// assert_eq!(map["poneyland"], 43);
146 /// ```
147 pub fn and_modify<F>(self, f: F) -> Self
148 where
149 F: FnOnce(&mut V),
150 {
151 match self {
152 Entry::Occupied(mut o) => {
153 f(o.get_mut());
154 Entry::Occupied(o)
155 }
156 x => x,
157 }
158 }
159
160 /// Ensures a value is in the entry by inserting the default value if empty,
161 /// and returns a mutable reference to the value in the entry.
162 ///
163 /// # Examples
164 ///
165 /// ```
166 /// # fn main() {
167 /// use vecmap::VecMap;
168 ///
169 /// let mut map: VecMap<&str, Option<u32>> = VecMap::new();
170 /// map.entry("poneyland").or_default();
171 ///
172 /// assert_eq!(map["poneyland"], None);
173 /// # }
174 /// ```
175 pub fn or_default(self) -> &'a mut V
176 where
177 V: Default,
178 {
179 match self {
180 Entry::Occupied(entry) => entry.into_mut(),
181 Entry::Vacant(entry) => entry.insert(V::default()),
182 }
183 }
184}
185
186/// A view into an occupied entry in a `VecMap`. It is part of the [`Entry`] enum.
187#[derive(Debug)]
188pub struct OccupiedEntry<'a, K, V> {
189 map: &'a mut VecMap<K, V>,
190 key: K,
191 index: usize,
192}
193
194impl<'a, K, V> OccupiedEntry<'a, K, V> {
195 pub(super) fn new(map: &'a mut VecMap<K, V>, key: K, index: usize) -> OccupiedEntry<'a, K, V> {
196 OccupiedEntry { map, key, index }
197 }
198
199 /// Gets a reference to the key in the entry.
200 ///
201 /// # Examples
202 ///
203 /// ```
204 /// use vecmap::VecMap;
205 ///
206 /// let mut map: VecMap<&str, u32> = VecMap::new();
207 /// map.entry("poneyland").or_insert(12);
208 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
209 /// ```
210 pub fn key(&self) -> &K {
211 &self.key
212 }
213
214 /// Gets the index of the entry.
215 ///
216 /// # Examples
217 ///
218 /// ```
219 /// use vecmap::VecMap;
220 ///
221 /// let mut map: VecMap<&str, u32> = VecMap::new();
222 /// map.entry("poneyland").or_insert(12);
223 /// assert_eq!(map.entry("poneyland").index(), 0);
224 /// ```
225 pub fn index(&self) -> usize {
226 self.index
227 }
228
229 /// Take ownership of the key.
230 ///
231 /// # Examples
232 ///
233 /// ```
234 /// use vecmap::VecMap;
235 /// use vecmap::map::Entry;
236 ///
237 /// let mut map: VecMap<&str, u32> = VecMap::new();
238 /// map.insert("foo", 1);
239 ///
240 /// if let Entry::Occupied(v) = map.entry("foo") {
241 /// v.into_key();
242 /// }
243 /// ```
244 pub fn into_key(self) -> K {
245 self.key
246 }
247
248 /// Gets a reference to the value in the entry.
249 ///
250 /// # Examples
251 ///
252 /// ```
253 /// use vecmap::VecMap;
254 /// use vecmap::map::Entry;
255 ///
256 /// let mut map: VecMap<&str, u32> = VecMap::new();
257 /// map.entry("poneyland").or_insert(12);
258 ///
259 /// if let Entry::Occupied(o) = map.entry("poneyland") {
260 /// assert_eq!(o.get(), &12);
261 /// }
262 /// ```
263 pub fn get(&self) -> &V {
264 &self.map[self.index]
265 }
266
267 /// Gets a mutable reference to the value in the entry.
268 ///
269 /// If you need a reference to the `OccupiedEntry` which may outlive the
270 /// destruction of the `Entry` value, see [`into_mut`].
271 ///
272 /// [`into_mut`]: Self::into_mut
273 ///
274 /// # Examples
275 ///
276 /// ```
277 /// use vecmap::VecMap;
278 /// use vecmap::map::Entry;
279 ///
280 /// let mut map: VecMap<&str, u32> = VecMap::new();
281 /// map.entry("poneyland").or_insert(12);
282 ///
283 /// assert_eq!(map["poneyland"], 12);
284 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
285 /// *o.get_mut() += 10;
286 /// assert_eq!(*o.get(), 22);
287 ///
288 /// // We can use the same Entry multiple times.
289 /// *o.get_mut() += 2;
290 /// }
291 ///
292 /// assert_eq!(map["poneyland"], 24);
293 /// ```
294 pub fn get_mut(&mut self) -> &mut V {
295 &mut self.map[self.index]
296 }
297
298 /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
299 /// with a lifetime bound to the map itself.
300 ///
301 /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
302 ///
303 /// [`get_mut`]: Self::get_mut
304 ///
305 /// # Examples
306 ///
307 /// ```
308 /// use vecmap::VecMap;
309 /// use vecmap::map::Entry;
310 ///
311 /// let mut map: VecMap<&str, u32> = VecMap::new();
312 /// map.entry("poneyland").or_insert(12);
313 ///
314 /// assert_eq!(map["poneyland"], 12);
315 /// if let Entry::Occupied(o) = map.entry("poneyland") {
316 /// *o.into_mut() += 10;
317 /// }
318 ///
319 /// assert_eq!(map["poneyland"], 22);
320 /// ```
321 pub fn into_mut(self) -> &'a mut V {
322 &mut self.map[self.index]
323 }
324
325 /// Sets the value of the entry, and returns the entry's old value.
326 ///
327 /// # Examples
328 ///
329 /// ```
330 /// use vecmap::VecMap;
331 /// use vecmap::map::Entry;
332 ///
333 /// let mut map: VecMap<&str, u32> = VecMap::new();
334 /// map.entry("poneyland").or_insert(12);
335 ///
336 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
337 /// assert_eq!(o.insert(15), 12);
338 /// }
339 ///
340 /// assert_eq!(map["poneyland"], 15);
341 /// ```
342 pub fn insert(&mut self, value: V) -> V {
343 mem::replace(self.get_mut(), value)
344 }
345
346 /// Removes and return the key-value pair stored in the map for this entry.
347 ///
348 /// Like `Vec::swap_remove`, the pair is removed by swapping it with the last element of the
349 /// map and popping it off. **This perturbs the position of what used to be the last
350 /// element!**
351 ///
352 /// # Examples
353 ///
354 /// ```
355 /// use vecmap::VecMap;
356 /// use vecmap::map::Entry;
357 ///
358 /// let mut map: VecMap<&str, u32> = VecMap::new();
359 /// map.entry("poneyland").or_insert(12);
360 /// map.entry("foo").or_insert(13);
361 /// map.entry("bar").or_insert(14);
362 ///
363 /// if let Entry::Occupied(o) = map.entry("poneyland") {
364 /// // We delete the entry from the map.
365 /// o.swap_remove_entry();
366 /// }
367 ///
368 /// assert_eq!(map.contains_key("poneyland"), false);
369 /// assert_eq!(map.get_index_of("foo"), Some(1));
370 /// assert_eq!(map.get_index_of("bar"), Some(0));
371 /// ```
372 pub fn swap_remove_entry(self) -> (K, V) {
373 self.map.swap_remove_index(self.index)
374 }
375
376 /// Removes and return the key-value pair stored in the map for this entry.
377 ///
378 /// Like `Vec::remove`, the pair is removed by shifting all of the elements that follow it,
379 /// preserving their relative order. **This perturbs the index of all of those elements!**
380 ///
381 /// # Examples
382 ///
383 /// ```
384 /// use vecmap::VecMap;
385 /// use vecmap::map::Entry;
386 ///
387 /// let mut map: VecMap<&str, u32> = VecMap::new();
388 /// map.entry("poneyland").or_insert(12);
389 /// map.entry("foo").or_insert(13);
390 /// map.entry("bar").or_insert(14);
391 ///
392 /// if let Entry::Occupied(o) = map.entry("poneyland") {
393 /// // We delete the entry from the map.
394 /// o.remove_entry();
395 /// }
396 ///
397 /// assert_eq!(map.contains_key("poneyland"), false);
398 /// assert_eq!(map.get_index_of("foo"), Some(0));
399 /// assert_eq!(map.get_index_of("bar"), Some(1));
400 /// ```
401 pub fn remove_entry(self) -> (K, V) {
402 self.map.remove_index(self.index)
403 }
404
405 /// Removes the key-value pair stored in the map for this entry, and return the value.
406 ///
407 /// Like `Vec::swap_remove`, the pair is removed by swapping it with the last element of the
408 /// map and popping it off. **This perturbs the position of what used to be the last
409 /// element!**
410 ///
411 /// # Examples
412 ///
413 /// ```
414 /// use vecmap::VecMap;
415 /// use vecmap::map::Entry;
416 ///
417 /// let mut map: VecMap<&str, u32> = VecMap::new();
418 /// map.entry("poneyland").or_insert(12);
419 /// map.entry("foo").or_insert(13);
420 /// map.entry("bar").or_insert(14);
421 ///
422 /// if let Entry::Occupied(o) = map.entry("poneyland") {
423 /// assert_eq!(o.swap_remove(), 12);
424 /// }
425 ///
426 /// assert_eq!(map.contains_key("poneyland"), false);
427 /// assert_eq!(map.get_index_of("foo"), Some(1));
428 /// assert_eq!(map.get_index_of("bar"), Some(0));
429 /// ```
430 pub fn swap_remove(self) -> V {
431 self.swap_remove_entry().1
432 }
433
434 /// Removes the key-value pair stored in the map for this entry, and return the value.
435 ///
436 /// Like `Vec::remove`, the pair is removed by shifting all of the elements that follow it,
437 /// preserving their relative order. **This perturbs the index of all of those elements!**
438 ///
439 /// # Examples
440 ///
441 /// ```
442 /// use vecmap::VecMap;
443 /// use vecmap::map::Entry;
444 ///
445 /// let mut map: VecMap<&str, u32> = VecMap::new();
446 /// map.entry("poneyland").or_insert(12);
447 /// map.entry("foo").or_insert(13);
448 /// map.entry("bar").or_insert(14);
449 ///
450 /// if let Entry::Occupied(o) = map.entry("poneyland") {
451 /// assert_eq!(o.remove(), 12);
452 /// }
453 ///
454 /// assert_eq!(map.contains_key("poneyland"), false);
455 /// assert_eq!(map.get_index_of("foo"), Some(0));
456 /// assert_eq!(map.get_index_of("bar"), Some(1));
457 /// ```
458 pub fn remove(self) -> V {
459 self.remove_entry().1
460 }
461}
462
463/// A view into a vacant entry in a `VecMap`. It is part of the [`Entry`] enum.
464#[derive(Debug)]
465pub struct VacantEntry<'a, K, V> {
466 map: &'a mut VecMap<K, V>,
467 key: K,
468}
469
470impl<'a, K, V> VacantEntry<'a, K, V> {
471 pub(super) fn new(map: &'a mut VecMap<K, V>, key: K) -> VacantEntry<'a, K, V> {
472 VacantEntry { map, key }
473 }
474
475 /// Gets a reference to the key that would be used when inserting a value through the
476 /// `VacantEntry`.
477 ///
478 /// # Examples
479 ///
480 /// ```
481 /// use vecmap::VecMap;
482 ///
483 /// let mut map: VecMap<&str, u32> = VecMap::new();
484 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
485 /// ```
486 pub fn key(&self) -> &K {
487 &self.key
488 }
489
490 /// Return the index where the key-value pair will be inserted.
491 ///
492 /// # Examples
493 ///
494 /// ```
495 /// use vecmap::VecMap;
496 ///
497 /// let mut map: VecMap<&str, u32> = VecMap::new();
498 /// assert_eq!(map.entry("poneyland").index(), 0);
499 /// ```
500 pub fn index(&self) -> usize {
501 self.map.len()
502 }
503
504 /// Take ownership of the key.
505 ///
506 /// # Examples
507 ///
508 /// ```
509 /// use vecmap::VecMap;
510 /// use vecmap::map::Entry;
511 ///
512 /// let mut map: VecMap<&str, u32> = VecMap::new();
513 ///
514 /// if let Entry::Vacant(v) = map.entry("poneyland") {
515 /// v.into_key();
516 /// }
517 /// ```
518 pub fn into_key(self) -> K {
519 self.key
520 }
521
522 /// Sets the value of the entry with the `VacantEntry`'s key, and returns a mutable reference
523 /// to it.
524 ///
525 /// # Examples
526 ///
527 /// ```
528 /// use vecmap::VecMap;
529 /// use vecmap::map::Entry;
530 ///
531 /// let mut map: VecMap<&str, u32> = VecMap::new();
532 ///
533 /// if let Entry::Vacant(o) = map.entry("poneyland") {
534 /// o.insert(37);
535 /// }
536 /// assert_eq!(map["poneyland"], 37);
537 /// ```
538 pub fn insert(self, value: V) -> &'a mut V {
539 let index = self.map.push(self.key, value);
540 &mut self.map[index]
541 }
542}