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}