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}