Skip to main content

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    /// Sets the value of the entry, and returns an `OccupiedEntry`.
186    ///
187    /// # Examples
188    ///
189    /// ```
190    /// use vecmap::VecMap;
191    ///
192    /// let mut map: VecMap<&str, String> = VecMap::new();
193    /// let entry = map.entry("poneyland").insert_entry("hoho".to_string());
194    ///
195    /// assert_eq!(entry.key(), &"poneyland");
196    /// ```
197    pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V>
198    where
199        K: Clone,
200    {
201        match self {
202            Entry::Occupied(mut entry) => {
203                entry.insert(value);
204                entry
205            }
206            Entry::Vacant(entry) => entry.insert_entry(value),
207        }
208    }
209}
210
211/// A view into an occupied entry in a `VecMap`. It is part of the [`Entry`] enum.
212#[derive(Debug)]
213pub struct OccupiedEntry<'a, K, V> {
214    map: &'a mut VecMap<K, V>,
215    key: K,
216    index: usize,
217}
218
219impl<'a, K, V> OccupiedEntry<'a, K, V> {
220    pub(super) fn new(map: &'a mut VecMap<K, V>, key: K, index: usize) -> OccupiedEntry<'a, K, V> {
221        OccupiedEntry { map, key, index }
222    }
223
224    /// Gets a reference to the key in the entry.
225    ///
226    /// # Examples
227    ///
228    /// ```
229    /// use vecmap::VecMap;
230    ///
231    /// let mut map: VecMap<&str, u32> = VecMap::new();
232    /// map.entry("poneyland").or_insert(12);
233    /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
234    /// ```
235    pub fn key(&self) -> &K {
236        &self.key
237    }
238
239    /// Gets the index of the entry.
240    ///
241    /// # Examples
242    ///
243    /// ```
244    /// use vecmap::VecMap;
245    ///
246    /// let mut map: VecMap<&str, u32> = VecMap::new();
247    /// map.entry("poneyland").or_insert(12);
248    /// assert_eq!(map.entry("poneyland").index(), 0);
249    /// ```
250    pub fn index(&self) -> usize {
251        self.index
252    }
253
254    /// Take ownership of the key.
255    ///
256    /// # Examples
257    ///
258    /// ```
259    /// use vecmap::VecMap;
260    /// use vecmap::map::Entry;
261    ///
262    /// let mut map: VecMap<&str, u32> = VecMap::new();
263    /// map.insert("foo", 1);
264    ///
265    /// if let Entry::Occupied(v) = map.entry("foo") {
266    ///     v.into_key();
267    /// }
268    /// ```
269    pub fn into_key(self) -> K {
270        self.key
271    }
272
273    /// Gets a reference to the value in the entry.
274    ///
275    /// # Examples
276    ///
277    /// ```
278    /// use vecmap::VecMap;
279    /// use vecmap::map::Entry;
280    ///
281    /// let mut map: VecMap<&str, u32> = VecMap::new();
282    /// map.entry("poneyland").or_insert(12);
283    ///
284    /// if let Entry::Occupied(o) = map.entry("poneyland") {
285    ///     assert_eq!(o.get(), &12);
286    /// }
287    /// ```
288    pub fn get(&self) -> &V {
289        &self.map[self.index]
290    }
291
292    /// Gets a mutable reference to the value in the entry.
293    ///
294    /// If you need a reference to the `OccupiedEntry` which may outlive the
295    /// destruction of the `Entry` value, see [`into_mut`].
296    ///
297    /// [`into_mut`]: Self::into_mut
298    ///
299    /// # Examples
300    ///
301    /// ```
302    /// use vecmap::VecMap;
303    /// use vecmap::map::Entry;
304    ///
305    /// let mut map: VecMap<&str, u32> = VecMap::new();
306    /// map.entry("poneyland").or_insert(12);
307    ///
308    /// assert_eq!(map["poneyland"], 12);
309    /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
310    ///     *o.get_mut() += 10;
311    ///     assert_eq!(*o.get(), 22);
312    ///
313    ///     // We can use the same Entry multiple times.
314    ///     *o.get_mut() += 2;
315    /// }
316    ///
317    /// assert_eq!(map["poneyland"], 24);
318    /// ```
319    pub fn get_mut(&mut self) -> &mut V {
320        &mut self.map[self.index]
321    }
322
323    /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
324    /// with a lifetime bound to the map itself.
325    ///
326    /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
327    ///
328    /// [`get_mut`]: Self::get_mut
329    ///
330    /// # Examples
331    ///
332    /// ```
333    /// use vecmap::VecMap;
334    /// use vecmap::map::Entry;
335    ///
336    /// let mut map: VecMap<&str, u32> = VecMap::new();
337    /// map.entry("poneyland").or_insert(12);
338    ///
339    /// assert_eq!(map["poneyland"], 12);
340    /// if let Entry::Occupied(o) = map.entry("poneyland") {
341    ///     *o.into_mut() += 10;
342    /// }
343    ///
344    /// assert_eq!(map["poneyland"], 22);
345    /// ```
346    pub fn into_mut(self) -> &'a mut V {
347        &mut self.map[self.index]
348    }
349
350    /// Sets the value of the entry, and returns the entry's old value.
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    ///
361    /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
362    ///     assert_eq!(o.insert(15), 12);
363    /// }
364    ///
365    /// assert_eq!(map["poneyland"], 15);
366    /// ```
367    pub fn insert(&mut self, value: V) -> V {
368        mem::replace(self.get_mut(), value)
369    }
370
371    /// Removes and return the key-value pair stored in the map for this entry.
372    ///
373    /// Like `Vec::swap_remove`, the pair is removed by swapping it with the last element of the
374    /// map and popping it off. **This perturbs the position of what used to be the last
375    /// element!**
376    ///
377    /// # Examples
378    ///
379    /// ```
380    /// use vecmap::VecMap;
381    /// use vecmap::map::Entry;
382    ///
383    /// let mut map: VecMap<&str, u32> = VecMap::new();
384    /// map.entry("poneyland").or_insert(12);
385    /// map.entry("foo").or_insert(13);
386    /// map.entry("bar").or_insert(14);
387    ///
388    /// if let Entry::Occupied(o) = map.entry("poneyland") {
389    ///     // We delete the entry from the map.
390    ///     o.swap_remove_entry();
391    /// }
392    ///
393    /// assert_eq!(map.contains_key("poneyland"), false);
394    /// assert_eq!(map.get_index_of("foo"), Some(1));
395    /// assert_eq!(map.get_index_of("bar"), Some(0));
396    /// ```
397    pub fn swap_remove_entry(self) -> (K, V) {
398        self.map.swap_remove_index(self.index)
399    }
400
401    /// Removes and return the key-value pair stored in the map for this entry.
402    ///
403    /// Like `Vec::remove`, the pair is removed by shifting all of the elements that follow it,
404    /// preserving their relative order. **This perturbs the index of all of those elements!**
405    ///
406    /// # Examples
407    ///
408    /// ```
409    /// use vecmap::VecMap;
410    /// use vecmap::map::Entry;
411    ///
412    /// let mut map: VecMap<&str, u32> = VecMap::new();
413    /// map.entry("poneyland").or_insert(12);
414    /// map.entry("foo").or_insert(13);
415    /// map.entry("bar").or_insert(14);
416    ///
417    /// if let Entry::Occupied(o) = map.entry("poneyland") {
418    ///     // We delete the entry from the map.
419    ///     o.remove_entry();
420    /// }
421    ///
422    /// assert_eq!(map.contains_key("poneyland"), false);
423    /// assert_eq!(map.get_index_of("foo"), Some(0));
424    /// assert_eq!(map.get_index_of("bar"), Some(1));
425    /// ```
426    pub fn remove_entry(self) -> (K, V) {
427        self.map.remove_index(self.index)
428    }
429
430    /// Removes the key-value pair stored in the map for this entry, and return the value.
431    ///
432    /// Like `Vec::swap_remove`, the pair is removed by swapping it with the last element of the
433    /// map and popping it off. **This perturbs the position of what used to be the last
434    /// element!**
435    ///
436    /// # Examples
437    ///
438    /// ```
439    /// use vecmap::VecMap;
440    /// use vecmap::map::Entry;
441    ///
442    /// let mut map: VecMap<&str, u32> = VecMap::new();
443    /// map.entry("poneyland").or_insert(12);
444    /// map.entry("foo").or_insert(13);
445    /// map.entry("bar").or_insert(14);
446    ///
447    /// if let Entry::Occupied(o) = map.entry("poneyland") {
448    ///     assert_eq!(o.swap_remove(), 12);
449    /// }
450    ///
451    /// assert_eq!(map.contains_key("poneyland"), false);
452    /// assert_eq!(map.get_index_of("foo"), Some(1));
453    /// assert_eq!(map.get_index_of("bar"), Some(0));
454    /// ```
455    pub fn swap_remove(self) -> V {
456        self.swap_remove_entry().1
457    }
458
459    /// Removes the key-value pair stored in the map for this entry, and return the value.
460    ///
461    /// Like `Vec::remove`, the pair is removed by shifting all of the elements that follow it,
462    /// preserving their relative order. **This perturbs the index of all of those elements!**
463    ///
464    /// # Examples
465    ///
466    /// ```
467    /// use vecmap::VecMap;
468    /// use vecmap::map::Entry;
469    ///
470    /// let mut map: VecMap<&str, u32> = VecMap::new();
471    /// map.entry("poneyland").or_insert(12);
472    /// map.entry("foo").or_insert(13);
473    /// map.entry("bar").or_insert(14);
474    ///
475    /// if let Entry::Occupied(o) = map.entry("poneyland") {
476    ///     assert_eq!(o.remove(), 12);
477    /// }
478    ///
479    /// assert_eq!(map.contains_key("poneyland"), false);
480    /// assert_eq!(map.get_index_of("foo"), Some(0));
481    /// assert_eq!(map.get_index_of("bar"), Some(1));
482    /// ```
483    pub fn remove(self) -> V {
484        self.remove_entry().1
485    }
486}
487
488/// A view into a vacant entry in a `VecMap`. It is part of the [`Entry`] enum.
489#[derive(Debug)]
490pub struct VacantEntry<'a, K, V> {
491    map: &'a mut VecMap<K, V>,
492    key: K,
493}
494
495impl<'a, K, V> VacantEntry<'a, K, V> {
496    pub(super) fn new(map: &'a mut VecMap<K, V>, key: K) -> VacantEntry<'a, K, V> {
497        VacantEntry { map, key }
498    }
499
500    /// Gets a reference to the key that would be used when inserting a value through the
501    /// `VacantEntry`.
502    ///
503    /// # Examples
504    ///
505    /// ```
506    /// use vecmap::VecMap;
507    ///
508    /// let mut map: VecMap<&str, u32> = VecMap::new();
509    /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
510    /// ```
511    pub fn key(&self) -> &K {
512        &self.key
513    }
514
515    /// Return the index where the key-value pair will be inserted.
516    ///
517    /// # Examples
518    ///
519    /// ```
520    /// use vecmap::VecMap;
521    ///
522    /// let mut map: VecMap<&str, u32> = VecMap::new();
523    /// assert_eq!(map.entry("poneyland").index(), 0);
524    /// ```
525    pub fn index(&self) -> usize {
526        self.map.len()
527    }
528
529    /// Take ownership of the key.
530    ///
531    /// # Examples
532    ///
533    /// ```
534    /// use vecmap::VecMap;
535    /// use vecmap::map::Entry;
536    ///
537    /// let mut map: VecMap<&str, u32> = VecMap::new();
538    ///
539    /// if let Entry::Vacant(v) = map.entry("poneyland") {
540    ///     v.into_key();
541    /// }
542    /// ```
543    pub fn into_key(self) -> K {
544        self.key
545    }
546
547    /// Sets the value of the entry with the `VacantEntry`'s key, and returns a mutable reference
548    /// to it.
549    ///
550    /// # Examples
551    ///
552    /// ```
553    /// use vecmap::VecMap;
554    /// use vecmap::map::Entry;
555    ///
556    /// let mut map: VecMap<&str, u32> = VecMap::new();
557    ///
558    /// if let Entry::Vacant(o) = map.entry("poneyland") {
559    ///     o.insert(37);
560    /// }
561    /// assert_eq!(map["poneyland"], 37);
562    /// ```
563    pub fn insert(self, value: V) -> &'a mut V {
564        let index = self.map.push(self.key, value);
565        &mut self.map[index]
566    }
567
568    /// Sets the value of the entry with the `VacantEntry`'s key,
569    /// and returns an `OccupiedEntry`.
570    ///
571    /// # Examples
572    ///
573    /// ```
574    /// use vecmap::VecMap;
575    /// use vecmap::map::Entry;
576    ///
577    /// let mut map: VecMap<&str, u32> = VecMap::new();
578    ///
579    /// if let Entry::Vacant(o) = map.entry("poneyland") {
580    ///     o.insert_entry(37);
581    /// }
582    /// assert_eq!(map["poneyland"], 37);
583    /// ```
584    pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V>
585    where
586        K: Clone,
587    {
588        let index = self.map.push(self.key.clone(), value);
589
590        OccupiedEntry {
591            map: self.map,
592            key: self.key,
593            index,
594        }
595    }
596}