stable_map/entry.rs
1#[cfg(test)]
2mod tests;
3
4use {
5 crate::{
6 linear_storage::LinearStorage,
7 pos_vec::pos::{InUse, Pos},
8 },
9 core::{
10 borrow::Borrow,
11 fmt::{Debug, Formatter},
12 hash::{BuildHasher, Hash},
13 mem::{self},
14 },
15 hashbrown::hash_map,
16};
17
18/// A view into a single entry in a map, which may either be vacant or occupied.
19///
20/// This `enum` is constructed from the [`entry`] method on [`StableMap`].
21///
22/// [`StableMap`]: crate::StableMap
23/// [`entry`]: crate::StableMap::entry
24///
25/// # Examples
26///
27/// ```
28/// use stable_map::{Entry, StableMap, OccupiedEntry};
29///
30/// let mut map = StableMap::new();
31/// map.extend([("a", 10), ("b", 20), ("c", 30)]);
32/// assert_eq!(map.len(), 3);
33///
34/// // Existing key (insert)
35/// let entry: Entry<_, _, _> = map.entry("a");
36/// let _raw_o: OccupiedEntry<_, _, _> = entry.insert(1);
37/// assert_eq!(map.len(), 3);
38/// // Nonexistent key (insert)
39/// map.entry("d").insert(4);
40///
41/// // Existing key (or_insert)
42/// let v = map.entry("b").or_insert(2);
43/// assert_eq!(std::mem::replace(v, 2), 20);
44/// // Nonexistent key (or_insert)
45/// map.entry("e").or_insert(5);
46///
47/// // Existing key (or_insert_with)
48/// let v = map.entry("c").or_insert_with(|| 3);
49/// assert_eq!(std::mem::replace(v, 3), 30);
50/// // Nonexistent key (or_insert_with)
51/// map.entry("f").or_insert_with(|| 6);
52///
53/// println!("Our StableMap: {:?}", map);
54///
55/// let mut vec: Vec<_> = map.iter().map(|(&k, &v)| (k, v)).collect();
56/// // The `Iter` iterator produces items in arbitrary order, so the
57/// // items must be sorted to test them against a sorted array.
58/// vec.sort_unstable();
59/// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3), ("d", 4), ("e", 5), ("f", 6)]);
60/// ```
61pub enum Entry<'a, K, V, S> {
62 /// An occupied entry.
63 ///
64 /// # Examples
65 ///
66 /// ```
67 /// use stable_map::{Entry, StableMap};
68 /// let mut map: StableMap<_, _> = [("a", 100), ("b", 200)].into();
69 ///
70 /// match map.entry("a") {
71 /// Entry::Vacant(_) => unreachable!(),
72 /// Entry::Occupied(_) => { }
73 /// }
74 /// ```
75 Occupied(OccupiedEntry<'a, K, V, S>),
76 /// A vacant entry.
77 ///
78 /// # Examples
79 ///
80 /// ```
81 /// use stable_map::{Entry, StableMap};
82 /// let mut map: StableMap<&str, i32> = StableMap::new();
83 ///
84 /// match map.entry("a") {
85 /// Entry::Occupied(_) => unreachable!(),
86 /// Entry::Vacant(_) => { }
87 /// }
88 /// ```
89 Vacant(VacantEntry<'a, K, V, S>),
90}
91
92/// A view into a single entry in a map, which may either be vacant or occupied,
93/// with any borrowed form of the map's key type.
94///
95///
96/// This `enum` is constructed from the [`entry_ref`] method on [`StableMap`].
97///
98/// [`Hash`] and [`Eq`] on the borrowed form of the map's key type *must* match those
99/// for the key type. It also require that key may be constructed from the borrowed
100/// form through the [`From`] trait.
101///
102/// [`StableMap`]: crate::StableMap
103/// [`entry_ref`]: crate::StableMap::entry_ref
104/// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
105/// [`Hash`]: https://doc.rust-lang.org/std/hash/trait.Hash.html
106/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
107///
108/// # Examples
109///
110/// ```
111/// use stable_map::{EntryRef, StableMap, OccupiedEntry};
112///
113/// let mut map = StableMap::new();
114/// map.extend([("a".to_owned(), 10), ("b".into(), 20), ("c".into(), 30)]);
115/// assert_eq!(map.len(), 3);
116///
117/// // Existing key (insert)
118/// let key = String::from("a");
119/// let entry: EntryRef<_, _, _, _> = map.entry_ref(&key);
120/// let _raw_o: OccupiedEntry<_, _, _> = entry.insert(1);
121/// assert_eq!(map.len(), 3);
122/// // Nonexistent key (insert)
123/// map.entry_ref("d").insert(4);
124///
125/// // Existing key (or_insert)
126/// let v = map.entry_ref("b").or_insert(2);
127/// assert_eq!(std::mem::replace(v, 2), 20);
128/// // Nonexistent key (or_insert)
129/// map.entry_ref("e").or_insert(5);
130///
131/// // Existing key (or_insert_with)
132/// let v = map.entry_ref("c").or_insert_with(|| 3);
133/// assert_eq!(std::mem::replace(v, 3), 30);
134/// // Nonexistent key (or_insert_with)
135/// map.entry_ref("f").or_insert_with(|| 6);
136///
137/// println!("Our StableMap: {:?}", map);
138///
139/// for (key, value) in ["a", "b", "c", "d", "e", "f"].into_iter().zip(1..=6) {
140/// assert_eq!(map[key], value)
141/// }
142/// assert_eq!(map.len(), 6);
143/// ```
144pub enum EntryRef<'a, 'b, K, Q: ?Sized, V, S> {
145 /// An occupied entry.
146 ///
147 /// # Examples
148 ///
149 /// ```
150 /// use stable_map::{EntryRef, StableMap};
151 /// let mut map: StableMap<_, _> = [("a".to_owned(), 100), ("b".into(), 200)].into();
152 ///
153 /// match map.entry_ref("a") {
154 /// EntryRef::Vacant(_) => unreachable!(),
155 /// EntryRef::Occupied(_) => { }
156 /// }
157 /// ```
158 Occupied(OccupiedEntry<'a, K, V, S>),
159 /// A vacant entry.
160 ///
161 /// # Examples
162 ///
163 /// ```
164 /// use stable_map::{EntryRef, StableMap};
165 /// let mut map: StableMap<String, i32> = StableMap::new();
166 ///
167 /// match map.entry_ref("a") {
168 /// EntryRef::Occupied(_) => unreachable!(),
169 /// EntryRef::Vacant(_) => { }
170 /// }
171 /// ```
172 Vacant(VacantEntryRef<'a, 'b, K, Q, V, S>),
173}
174
175/// A view into an occupied entry in a [`StableMap`](crate::StableMap).
176/// It is part of the [`Entry`] and [`EntryRef`] enums.
177///
178/// # Examples
179///
180/// ```
181/// use stable_map::{Entry, StableMap, OccupiedEntry};
182///
183/// let mut map = StableMap::new();
184/// map.extend([("a", 10), ("b", 20), ("c", 30)]);
185///
186/// let _entry_o: OccupiedEntry<_, _, _> = map.entry("a").insert(100);
187/// assert_eq!(map.len(), 3);
188///
189/// // Existing key (insert and update)
190/// match map.entry("a") {
191/// Entry::Vacant(_) => unreachable!(),
192/// Entry::Occupied(mut view) => {
193/// assert_eq!(view.get(), &100);
194/// let v = view.get_mut();
195/// *v *= 10;
196/// assert_eq!(view.insert(1111), 1000);
197/// }
198/// }
199///
200/// assert_eq!(map[&"a"], 1111);
201/// assert_eq!(map.len(), 3);
202///
203/// // Existing key (take)
204/// match map.entry("c") {
205/// Entry::Vacant(_) => unreachable!(),
206/// Entry::Occupied(view) => {
207/// assert_eq!(view.remove_entry(), ("c", 30));
208/// }
209/// }
210/// assert_eq!(map.get(&"c"), None);
211/// assert_eq!(map.len(), 2);
212/// ```
213pub struct OccupiedEntry<'a, K, V, S> {
214 pub(crate) entry: hash_map::OccupiedEntry<'a, K, Pos<InUse>, S>,
215 pub(crate) entries: &'a mut LinearStorage<V>,
216}
217
218/// A view into a vacant entry in a `StableMap`.
219/// It is part of the [`Entry`] enum.
220///
221/// # Examples
222///
223/// ```
224/// use stable_map::{Entry, StableMap, VacantEntry};
225///
226/// let mut map = StableMap::<&str, i32>::new();
227///
228/// let entry_v: VacantEntry<_, _, _> = match map.entry("a") {
229/// Entry::Vacant(view) => view,
230/// Entry::Occupied(_) => unreachable!(),
231/// };
232/// entry_v.insert(10);
233/// assert!(map[&"a"] == 10 && map.len() == 1);
234///
235/// // Nonexistent key (insert and update)
236/// match map.entry("b") {
237/// Entry::Occupied(_) => unreachable!(),
238/// Entry::Vacant(view) => {
239/// let value = view.insert(2);
240/// assert_eq!(*value, 2);
241/// *value = 20;
242/// }
243/// }
244/// assert!(map[&"b"] == 20 && map.len() == 2);
245/// ```
246pub struct VacantEntry<'a, K, V, S> {
247 pub(crate) entry: hash_map::VacantEntry<'a, K, Pos<InUse>, S>,
248 pub(crate) entries: &'a mut LinearStorage<V>,
249}
250
251/// A view into a vacant entry in a `StableMap`.
252/// It is part of the [`EntryRef`] enum.
253///
254/// # Examples
255///
256/// ```
257/// use stable_map::{EntryRef, StableMap, VacantEntryRef};
258///
259/// let mut map = StableMap::<String, i32>::new();
260///
261/// let entry_v: VacantEntryRef<_, _, _, _> = match map.entry_ref("a") {
262/// EntryRef::Vacant(view) => view,
263/// EntryRef::Occupied(_) => unreachable!(),
264/// };
265/// entry_v.insert(10);
266/// assert!(map["a"] == 10 && map.len() == 1);
267///
268/// // Nonexistent key (insert and update)
269/// match map.entry_ref("b") {
270/// EntryRef::Occupied(_) => unreachable!(),
271/// EntryRef::Vacant(view) => {
272/// let value = view.insert(2);
273/// assert_eq!(*value, 2);
274/// *value = 20;
275/// }
276/// }
277/// assert!(map["b"] == 20 && map.len() == 2);
278/// ```
279pub struct VacantEntryRef<'a, 'b, K, Q, V, S>
280where
281 Q: ?Sized,
282{
283 pub(crate) entry: hash_map::VacantEntryRef<'a, 'b, K, Q, Pos<InUse>, S>,
284 pub(crate) entries: &'a mut LinearStorage<V>,
285}
286
287impl<'a, K, V, S> OccupiedEntry<'a, K, V, S> {
288 /// Gets a reference to the value in the entry.
289 ///
290 /// # Examples
291 ///
292 /// ```
293 /// use stable_map::{Entry, StableMap};
294 ///
295 /// let mut map: StableMap<&str, u32> = StableMap::new();
296 /// map.entry("poneyland").or_insert(12);
297 ///
298 /// match map.entry("poneyland") {
299 /// Entry::Vacant(_) => panic!(),
300 /// Entry::Occupied(entry) => assert_eq!(entry.get(), &12),
301 /// }
302 /// ```
303 #[cfg_attr(feature = "inline-more", inline)]
304 pub fn get(&self) -> &V {
305 unsafe {
306 // SAFETY: By the invariants, self.entry.get() is valid.
307 self.entries.get_unchecked(self.entry.get())
308 }
309 }
310
311 /// Gets a mutable reference to the value in the entry.
312 ///
313 /// If you need a reference to the `OccupiedEntry` which may outlive the
314 /// destruction of the `Entry` value, see [`into_mut`](Self::into_mut).
315 ///
316 /// # Examples
317 ///
318 /// ```
319 /// use stable_map::{Entry, StableMap};
320 ///
321 /// let mut map: StableMap<&str, u32> = StableMap::new();
322 /// map.entry("poneyland").or_insert(12);
323 ///
324 /// assert_eq!(map["poneyland"], 12);
325 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
326 /// *o.get_mut() += 10;
327 /// assert_eq!(*o.get(), 22);
328 ///
329 /// // We can use the same Entry multiple times.
330 /// *o.get_mut() += 2;
331 /// }
332 ///
333 /// assert_eq!(map["poneyland"], 24);
334 /// ```
335 #[cfg_attr(feature = "inline-more", inline)]
336 pub fn get_mut(&mut self) -> &mut V {
337 unsafe {
338 // SAFETY: By the invariants, self.entry.get() is valid.
339 self.entries.get_unchecked_mut(self.entry.get())
340 }
341 }
342
343 /// Sets the value of the entry, and returns the entry's old value.
344 ///
345 /// # Examples
346 ///
347 /// ```
348 /// use stable_map::{Entry, StableMap};
349 ///
350 /// let mut map: StableMap<&str, u32> = StableMap::new();
351 /// map.entry("poneyland").or_insert(12);
352 ///
353 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
354 /// assert_eq!(o.insert(15), 12);
355 /// }
356 ///
357 /// assert_eq!(map["poneyland"], 15);
358 /// ```
359 #[cfg_attr(feature = "inline-more", inline)]
360 pub fn insert(&mut self, value: V) -> V {
361 mem::replace(self.get_mut(), value)
362 }
363
364 /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
365 /// with a lifetime bound to the map itself.
366 ///
367 /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`](Self::get_mut).
368 ///
369 /// # Examples
370 ///
371 /// ```
372 /// use stable_map::{Entry, StableMap};
373 ///
374 /// let mut map: StableMap<&str, u32> = StableMap::new();
375 /// map.entry("poneyland").or_insert(12);
376 ///
377 /// assert_eq!(map["poneyland"], 12);
378 ///
379 /// let value: &mut u32;
380 /// match map.entry("poneyland") {
381 /// Entry::Occupied(entry) => value = entry.into_mut(),
382 /// Entry::Vacant(_) => panic!(),
383 /// }
384 /// *value += 10;
385 ///
386 /// assert_eq!(map["poneyland"], 22);
387 /// ```
388 #[cfg_attr(feature = "inline-more", inline)]
389 pub fn into_mut(self) -> &'a mut V {
390 unsafe {
391 // SAFETY: By the invariants, self.entry.get() is valid.
392 self.entries.get_unchecked_mut(self.entry.get())
393 }
394 }
395
396 /// Gets a reference to the key in the entry.
397 ///
398 /// # Examples
399 ///
400 /// ```
401 /// use stable_map::{Entry, StableMap};
402 ///
403 /// let mut map: StableMap<&str, u32> = StableMap::new();
404 /// map.entry("poneyland").or_insert(12);
405 ///
406 /// match map.entry("poneyland") {
407 /// Entry::Vacant(_) => panic!(),
408 /// Entry::Occupied(entry) => assert_eq!(entry.key(), &"poneyland"),
409 /// }
410 /// ```
411 #[cfg_attr(feature = "inline-more", inline)]
412 pub fn key(&self) -> &K {
413 self.entry.key()
414 }
415
416 /// Takes the value out of the entry, and returns it.
417 /// Keeps the allocated memory for reuse.
418 ///
419 /// # Examples
420 ///
421 /// ```
422 /// use stable_map::{Entry, StableMap};
423 ///
424 /// let mut map: StableMap<&str, u32> = StableMap::new();
425 /// // The map is empty
426 /// assert!(map.is_empty() && map.capacity() == 0);
427 ///
428 /// map.entry("poneyland").or_insert(12);
429 ///
430 /// if let Entry::Occupied(o) = map.entry("poneyland") {
431 /// assert_eq!(o.remove(), 12);
432 /// }
433 ///
434 /// assert_eq!(map.contains_key("poneyland"), false);
435 /// // Now map hold none elements
436 /// assert!(map.is_empty());
437 /// ```
438 #[cfg_attr(feature = "inline-more", inline)]
439 pub fn remove(self) -> V {
440 let pos = self.entry.remove();
441 unsafe {
442 // SAFETY: By the invariants, self.entry.get() is valid.
443 self.entries.take_unchecked(pos)
444 }
445 }
446
447 /// Take the ownership of the key and value from the map.
448 /// Keeps the allocated memory for reuse.
449 ///
450 /// # Examples
451 ///
452 /// ```
453 /// use stable_map::{Entry, StableMap};
454 ///
455 /// let mut map: StableMap<&str, u32> = StableMap::new();
456 /// // The map is empty
457 /// assert!(map.is_empty() && map.capacity() == 0);
458 ///
459 /// map.entry("poneyland").or_insert(12);
460 ///
461 /// if let Entry::Occupied(o) = map.entry("poneyland") {
462 /// // We delete the entry from the map.
463 /// assert_eq!(o.remove_entry(), ("poneyland", 12));
464 /// }
465 ///
466 /// assert_eq!(map.contains_key("poneyland"), false);
467 /// // Now map hold none elements
468 /// assert!(map.is_empty());
469 /// ```
470 #[cfg_attr(feature = "inline-more", inline)]
471 pub fn remove_entry(self) -> (K, V) {
472 let (k, pos) = self.entry.remove_entry();
473 let value = unsafe {
474 // SAFETY: By the invariants, self.entry.get() is valid.
475 self.entries.take_unchecked(pos)
476 };
477 (k, value)
478 }
479
480 /// Provides shared access to the key and owned access to the value of
481 /// the entry and allows to replace or remove it based on the
482 /// value of the returned option.
483 ///
484 /// # Examples
485 ///
486 /// ```
487 /// use stable_map::{Entry, StableMap};
488 ///
489 /// let mut map: StableMap<&str, u32> = StableMap::new();
490 /// map.insert("poneyland", 42);
491 ///
492 /// let entry = match map.entry("poneyland") {
493 /// Entry::Occupied(e) => {
494 /// e.replace_entry_with(|k, v| {
495 /// assert_eq!(k, &"poneyland");
496 /// assert_eq!(v, 42);
497 /// Some(v + 1)
498 /// })
499 /// }
500 /// Entry::Vacant(_) => panic!(),
501 /// };
502 ///
503 /// match entry {
504 /// Entry::Occupied(e) => {
505 /// assert_eq!(e.key(), &"poneyland");
506 /// assert_eq!(e.get(), &43);
507 /// }
508 /// Entry::Vacant(_) => panic!(),
509 /// }
510 ///
511 /// assert_eq!(map["poneyland"], 43);
512 ///
513 /// let entry = match map.entry("poneyland") {
514 /// Entry::Occupied(e) => e.replace_entry_with(|_k, _v| None),
515 /// Entry::Vacant(_) => panic!(),
516 /// };
517 ///
518 /// match entry {
519 /// Entry::Vacant(e) => {
520 /// assert_eq!(e.key(), &"poneyland");
521 /// }
522 /// Entry::Occupied(_) => panic!(),
523 /// }
524 ///
525 /// assert!(!map.contains_key("poneyland"));
526 /// ```
527 #[cfg_attr(feature = "inline-more", inline)]
528 pub fn replace_entry_with<F>(self, f: F) -> Entry<'a, K, V, S>
529 where
530 F: FnOnce(&K, V) -> Option<V>,
531 {
532 let entry = self.entry.replace_entry_with(|k, pos| {
533 let v = unsafe { self.entries.take_unchecked(pos) };
534 match f(k, v) {
535 None => None,
536 Some(v) => Some(self.entries.insert(v)),
537 }
538 });
539 match entry {
540 hash_map::Entry::Occupied(o) => Entry::Occupied(OccupiedEntry {
541 entry: o,
542 entries: self.entries,
543 }),
544 hash_map::Entry::Vacant(v) => Entry::Vacant(VacantEntry {
545 entry: v,
546 entries: self.entries,
547 }),
548 }
549 }
550}
551
552impl<'a, K, V, S> VacantEntry<'a, K, V, S> {
553 /// Sets the value of the entry with the [`VacantEntry`]'s key,
554 /// and returns a mutable reference to it.
555 ///
556 /// # Examples
557 ///
558 /// ```
559 /// use stable_map::{Entry, StableMap};
560 ///
561 /// let mut map: StableMap<&str, u32> = StableMap::new();
562 ///
563 /// if let Entry::Vacant(o) = map.entry("poneyland") {
564 /// o.insert(37);
565 /// }
566 /// assert_eq!(map["poneyland"], 37);
567 /// ```
568 #[cfg_attr(feature = "inline-more", inline)]
569 pub fn insert(self, value: V) -> &'a mut V
570 where
571 K: Hash,
572 S: BuildHasher,
573 {
574 let pos = self.entries.insert(value);
575 let pos = self.entry.insert(pos);
576 unsafe { self.entries.get_unchecked_mut(pos) }
577 }
578
579 /// Sets the value of the entry with the [`VacantEntry`]'s key,
580 /// and returns an [`OccupiedEntry`].
581 ///
582 /// # Examples
583 ///
584 /// ```
585 /// use stable_map::{Entry, StableMap};
586 ///
587 /// let mut map: StableMap<&str, u32> = StableMap::new();
588 ///
589 /// if let Entry::Vacant(v) = map.entry("poneyland") {
590 /// let o = v.insert_entry(37);
591 /// assert_eq!(o.get(), &37);
592 /// }
593 /// ```
594 #[cfg_attr(feature = "inline-more", inline)]
595 pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, S>
596 where
597 K: Hash,
598 S: BuildHasher,
599 {
600 let pos = self.entries.insert(value);
601 let entry = self.entry.insert_entry(pos);
602 OccupiedEntry {
603 entry,
604 entries: self.entries,
605 }
606 }
607
608 /// Take ownership of the key.
609 ///
610 /// # Examples
611 ///
612 /// ```
613 /// use stable_map::{Entry, StableMap};
614 ///
615 /// let mut map: StableMap<&str, u32> = StableMap::new();
616 ///
617 /// match map.entry("poneyland") {
618 /// Entry::Occupied(_) => panic!(),
619 /// Entry::Vacant(v) => assert_eq!(v.into_key(), "poneyland"),
620 /// }
621 /// ```
622 #[cfg_attr(feature = "inline-more", inline)]
623 pub fn into_key(self) -> K {
624 self.entry.into_key()
625 }
626
627 /// Gets a reference to the key that would be used when inserting a value
628 /// through the `VacantEntry`.
629 ///
630 /// # Examples
631 ///
632 /// ```
633 /// use stable_map::StableMap;
634 ///
635 /// let mut map: StableMap<&str, u32> = StableMap::new();
636 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
637 /// ```
638 #[cfg_attr(feature = "inline-more", inline)]
639 pub fn key(&self) -> &K {
640 self.entry.key()
641 }
642}
643
644impl<'a, K, V, S> Entry<'a, K, V, S> {
645 /// Provides in-place mutable access to an occupied entry before any
646 /// potential inserts into the map.
647 ///
648 /// # Examples
649 ///
650 /// ```
651 /// use stable_map::StableMap;
652 ///
653 /// let mut map: StableMap<&str, u32> = StableMap::new();
654 ///
655 /// map.entry("poneyland")
656 /// .and_modify(|e| { *e += 1 })
657 /// .or_insert(42);
658 /// assert_eq!(map["poneyland"], 42);
659 ///
660 /// map.entry("poneyland")
661 /// .and_modify(|e| { *e += 1 })
662 /// .or_insert(42);
663 /// assert_eq!(map["poneyland"], 43);
664 /// ```
665 #[cfg_attr(feature = "inline-more", inline)]
666 pub fn and_modify<F>(mut self, f: F) -> Self
667 where
668 F: FnOnce(&mut V),
669 {
670 if let Entry::Occupied(e) = &mut self {
671 f(e.get_mut());
672 }
673 self
674 }
675
676 /// Provides shared access to the key and owned access to the value of
677 /// an occupied entry and allows to replace or remove it based on the
678 /// value of the returned option.
679 ///
680 /// # Examples
681 ///
682 /// ```
683 /// use stable_map::{Entry, StableMap};
684 ///
685 /// let mut map: StableMap<&str, u32> = StableMap::new();
686 ///
687 /// let entry = map
688 /// .entry("poneyland")
689 /// .and_replace_entry_with(|_k, _v| panic!());
690 ///
691 /// match entry {
692 /// Entry::Vacant(e) => {
693 /// assert_eq!(e.key(), &"poneyland");
694 /// }
695 /// Entry::Occupied(_) => panic!(),
696 /// }
697 ///
698 /// map.insert("poneyland", 42);
699 ///
700 /// let entry = map
701 /// .entry("poneyland")
702 /// .and_replace_entry_with(|k, v| {
703 /// assert_eq!(k, &"poneyland");
704 /// assert_eq!(v, 42);
705 /// Some(v + 1)
706 /// });
707 ///
708 /// match entry {
709 /// Entry::Occupied(e) => {
710 /// assert_eq!(e.key(), &"poneyland");
711 /// assert_eq!(e.get(), &43);
712 /// }
713 /// Entry::Vacant(_) => panic!(),
714 /// }
715 ///
716 /// assert_eq!(map["poneyland"], 43);
717 ///
718 /// let entry = map
719 /// .entry("poneyland")
720 /// .and_replace_entry_with(|_k, _v| None);
721 ///
722 /// match entry {
723 /// Entry::Vacant(e) => assert_eq!(e.key(), &"poneyland"),
724 /// Entry::Occupied(_) => panic!(),
725 /// }
726 ///
727 /// assert!(!map.contains_key("poneyland"));
728 /// ```
729 #[cfg_attr(feature = "inline-more", inline)]
730 pub fn and_replace_entry_with<F>(self, f: F) -> Self
731 where
732 F: FnOnce(&K, V) -> Option<V>,
733 {
734 match self {
735 Entry::Occupied(o) => o.replace_entry_with(f),
736 Entry::Vacant(v) => Entry::Vacant(v),
737 }
738 }
739
740 /// Sets the value of the entry, and returns an `OccupiedEntry`.
741 ///
742 /// # Examples
743 ///
744 /// ```
745 /// use stable_map::StableMap;
746 ///
747 /// let mut map: StableMap<&str, u32> = StableMap::new();
748 /// let entry = map.entry("horseyland").insert(37);
749 ///
750 /// assert_eq!(entry.key(), &"horseyland");
751 /// ```
752 #[cfg_attr(feature = "inline-more", inline)]
753 pub fn insert(self, value: V) -> OccupiedEntry<'a, K, V, S>
754 where
755 K: Hash,
756 S: BuildHasher,
757 {
758 match self {
759 Entry::Occupied(mut o) => {
760 o.insert(value);
761 o
762 }
763 Entry::Vacant(v) => v.insert_entry(value),
764 }
765 }
766
767 /// Returns a reference to this entry's key.
768 ///
769 /// # Examples
770 ///
771 /// ```
772 /// use stable_map::StableMap;
773 ///
774 /// let mut map: StableMap<&str, u32> = StableMap::new();
775 /// map.entry("poneyland").or_insert(3);
776 /// // existing key
777 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
778 /// // nonexistent key
779 /// assert_eq!(map.entry("horseland").key(), &"horseland");
780 /// ```
781 #[cfg_attr(feature = "inline-more", inline)]
782 pub fn key(&self) -> &K {
783 match self {
784 Entry::Occupied(e) => e.key(),
785 Entry::Vacant(e) => e.key(),
786 }
787 }
788
789 /// Ensures a value is in the entry by inserting the default value if empty,
790 /// and returns a mutable reference to the value in the entry.
791 ///
792 /// # Examples
793 ///
794 /// ```
795 /// use stable_map::StableMap;
796 ///
797 /// let mut map: StableMap<&str, Option<u32>> = StableMap::new();
798 ///
799 /// // nonexistent key
800 /// map.entry("poneyland").or_default();
801 /// assert_eq!(map["poneyland"], None);
802 ///
803 /// map.insert("horseland", Some(3));
804 ///
805 /// // existing key
806 /// assert_eq!(map.entry("horseland").or_default(), &mut Some(3));
807 /// ```
808 #[cfg_attr(feature = "inline-more", inline)]
809 pub fn or_default(self) -> &'a mut V
810 where
811 K: Hash,
812 S: BuildHasher,
813 V: Default,
814 {
815 match self {
816 Entry::Occupied(o) => o.into_mut(),
817 Entry::Vacant(v) => v.insert(V::default()),
818 }
819 }
820
821 /// Ensures a value is in the entry by inserting the default if empty, and returns
822 /// a mutable reference to the value in the entry.
823 ///
824 /// # Examples
825 ///
826 /// ```
827 /// use stable_map::StableMap;
828 ///
829 /// let mut map: StableMap<&str, u32> = StableMap::new();
830 ///
831 /// // nonexistent key
832 /// map.entry("poneyland").or_insert(3);
833 /// assert_eq!(map["poneyland"], 3);
834 ///
835 /// // existing key
836 /// *map.entry("poneyland").or_insert(10) *= 2;
837 /// assert_eq!(map["poneyland"], 6);
838 /// ```
839 #[cfg_attr(feature = "inline-more", inline)]
840 pub fn or_insert(self, value: V) -> &'a mut V
841 where
842 K: Hash,
843 S: BuildHasher,
844 {
845 match self {
846 Entry::Occupied(o) => o.into_mut(),
847 Entry::Vacant(v) => v.insert(value),
848 }
849 }
850
851 /// Ensures a value is in the entry by inserting the result of the default function if empty,
852 /// and returns a mutable reference to the value in the entry.
853 ///
854 /// # Examples
855 ///
856 /// ```
857 /// use stable_map::StableMap;
858 ///
859 /// let mut map: StableMap<&str, u32> = StableMap::new();
860 ///
861 /// // nonexistent key
862 /// map.entry("poneyland").or_insert_with(|| 3);
863 /// assert_eq!(map["poneyland"], 3);
864 ///
865 /// // existing key
866 /// *map.entry("poneyland").or_insert_with(|| 10) *= 2;
867 /// assert_eq!(map["poneyland"], 6);
868 /// ```
869 #[cfg_attr(feature = "inline-more", inline)]
870 pub fn or_insert_with<F>(self, f: F) -> &'a mut V
871 where
872 K: Hash,
873 S: BuildHasher,
874 F: FnOnce() -> V,
875 {
876 match self {
877 Entry::Occupied(o) => o.into_mut(),
878 Entry::Vacant(v) => v.insert(f()),
879 }
880 }
881
882 /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
883 /// This method allows for generating key-derived values for insertion by providing the default
884 /// function a reference to the key that was moved during the `.entry(key)` method call.
885 ///
886 /// The reference to the moved key is provided so that cloning or copying the key is
887 /// unnecessary, unlike with `.or_insert_with(|| ... )`.
888 ///
889 /// # Examples
890 ///
891 /// ```
892 /// use stable_map::StableMap;
893 ///
894 /// let mut map: StableMap<&str, usize> = StableMap::new();
895 ///
896 /// // nonexistent key
897 /// map.entry("poneyland").or_insert_with_key(|key| key.chars().count());
898 /// assert_eq!(map["poneyland"], 9);
899 ///
900 /// // existing key
901 /// *map.entry("poneyland").or_insert_with_key(|key| key.chars().count() * 10) *= 2;
902 /// assert_eq!(map["poneyland"], 18);
903 /// ```
904 #[cfg_attr(feature = "inline-more", inline)]
905 pub fn or_insert_with_key<F>(self, f: F) -> &'a mut V
906 where
907 K: Hash,
908 S: BuildHasher,
909 F: FnOnce(&K) -> V,
910 {
911 match self {
912 Entry::Occupied(o) => o.into_mut(),
913 Entry::Vacant(v) => {
914 let value = f(v.key());
915 v.insert(value)
916 }
917 }
918 }
919}
920
921impl<'a, 'b, K, Q, V, S> VacantEntryRef<'a, 'b, K, Q, V, S>
922where
923 Q: ?Sized,
924{
925 /// Sets the value of the entry, and returns an `OccupiedEntry`.
926 ///
927 /// # Examples
928 ///
929 /// ```
930 /// use stable_map::StableMap;
931 ///
932 /// let mut map: StableMap<String, u32> = StableMap::new();
933 /// let entry = map.entry_ref("horseyland").insert(37);
934 ///
935 /// assert_eq!(entry.key(), "horseyland");
936 /// ```
937 #[cfg_attr(feature = "inline-more", inline)]
938 pub fn insert(self, value: V) -> &'a mut V
939 where
940 K: Hash + From<&'b Q>,
941 S: BuildHasher,
942 {
943 let pos = self.entries.insert(value);
944 let pos = self.entry.insert(pos);
945 unsafe { self.entries.get_unchecked_mut(pos) }
946 }
947
948 /// Sets the value of the entry with the [`VacantEntryRef`]'s key,
949 /// and returns an [`OccupiedEntry`].
950 ///
951 /// # Examples
952 ///
953 /// ```
954 /// use stable_map::{EntryRef, StableMap};
955 ///
956 /// let mut map: StableMap<&str, u32> = StableMap::new();
957 ///
958 /// if let EntryRef::Vacant(v) = map.entry_ref("poneyland") {
959 /// let o = v.insert_entry(37);
960 /// assert_eq!(o.get(), &37);
961 /// }
962 /// ```
963 #[cfg_attr(feature = "inline-more", inline)]
964 pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, S>
965 where
966 K: Hash + From<&'b Q>,
967 S: BuildHasher,
968 {
969 let pos = self.entries.insert(value);
970 let entry = self.entry.insert_entry(pos);
971 OccupiedEntry {
972 entry,
973 entries: self.entries,
974 }
975 }
976
977 /// Gets a reference to the key that would be used when inserting a value
978 /// through the `VacantEntryRef`.
979 ///
980 /// # Examples
981 ///
982 /// ```
983 /// use stable_map::StableMap;
984 ///
985 /// let mut map: StableMap<String, u32> = StableMap::new();
986 /// let key: &str = "poneyland";
987 /// assert_eq!(map.entry_ref(key).key(), "poneyland");
988 /// ```
989 #[cfg_attr(feature = "inline-more", inline)]
990 pub fn key(&self) -> &'b Q {
991 self.entry.key()
992 }
993}
994
995impl<'a, 'b, K, Q, V, S> EntryRef<'a, 'b, K, Q, V, S>
996where
997 Q: ?Sized,
998{
999 /// Provides in-place mutable access to an occupied entry before any
1000 /// potential inserts into the map.
1001 ///
1002 /// # Examples
1003 ///
1004 /// ```
1005 /// use stable_map::StableMap;
1006 ///
1007 /// let mut map: StableMap<String, u32> = StableMap::new();
1008 ///
1009 /// map.entry_ref("poneyland")
1010 /// .and_modify(|e| { *e += 1 })
1011 /// .or_insert(42);
1012 /// assert_eq!(map["poneyland"], 42);
1013 ///
1014 /// map.entry_ref("poneyland")
1015 /// .and_modify(|e| { *e += 1 })
1016 /// .or_insert(42);
1017 /// assert_eq!(map["poneyland"], 43);
1018 /// ```
1019 #[cfg_attr(feature = "inline-more", inline)]
1020 pub fn and_modify<F>(mut self, f: F) -> Self
1021 where
1022 F: FnOnce(&mut V),
1023 {
1024 if let EntryRef::Occupied(e) = &mut self {
1025 f(e.get_mut());
1026 }
1027 self
1028 }
1029
1030 /// Sets the value of the entry, and returns an `OccupiedEntry`.
1031 ///
1032 /// # Examples
1033 ///
1034 /// ```
1035 /// use stable_map::StableMap;
1036 ///
1037 /// let mut map: StableMap<String, u32> = StableMap::new();
1038 /// let entry = map.entry_ref("horseyland").insert(37);
1039 ///
1040 /// assert_eq!(entry.key(), "horseyland");
1041 /// ```
1042 #[cfg_attr(feature = "inline-more", inline)]
1043 pub fn insert(self, value: V) -> OccupiedEntry<'a, K, V, S>
1044 where
1045 K: Hash + From<&'b Q>,
1046 S: BuildHasher,
1047 {
1048 match self {
1049 EntryRef::Occupied(mut o) => {
1050 o.insert(value);
1051 o
1052 }
1053 EntryRef::Vacant(v) => v.insert_entry(value),
1054 }
1055 }
1056
1057 /// Returns a reference to this entry's key.
1058 ///
1059 /// # Examples
1060 ///
1061 /// ```
1062 /// use stable_map::StableMap;
1063 ///
1064 /// let mut map: StableMap<String, u32> = StableMap::new();
1065 /// map.entry_ref("poneyland").or_insert(3);
1066 /// // existing key
1067 /// assert_eq!(map.entry_ref("poneyland").key(), "poneyland");
1068 /// // nonexistent key
1069 /// assert_eq!(map.entry_ref("horseland").key(), "horseland");
1070 /// ```
1071 #[cfg_attr(feature = "inline-more", inline)]
1072 pub fn key(&self) -> &Q
1073 where
1074 K: Borrow<Q>,
1075 {
1076 match self {
1077 EntryRef::Occupied(e) => e.key().borrow(),
1078 EntryRef::Vacant(e) => e.key(),
1079 }
1080 }
1081
1082 /// Ensures a value is in the entry by inserting the default value if empty,
1083 /// and returns a mutable reference to the value in the entry.
1084 ///
1085 /// # Examples
1086 ///
1087 /// ```
1088 /// use stable_map::StableMap;
1089 ///
1090 /// let mut map: StableMap<String, Option<u32>> = StableMap::new();
1091 ///
1092 /// // nonexistent key
1093 /// map.entry_ref("poneyland").or_default();
1094 /// assert_eq!(map["poneyland"], None);
1095 ///
1096 /// map.insert("horseland".to_string(), Some(3));
1097 ///
1098 /// // existing key
1099 /// assert_eq!(map.entry_ref("horseland").or_default(), &mut Some(3));
1100 /// ```
1101 #[cfg_attr(feature = "inline-more", inline)]
1102 pub fn or_default(self) -> &'a mut V
1103 where
1104 K: Hash + From<&'b Q>,
1105 S: BuildHasher,
1106 V: Default,
1107 {
1108 match self {
1109 EntryRef::Occupied(o) => o.into_mut(),
1110 EntryRef::Vacant(v) => v.insert(V::default()),
1111 }
1112 }
1113
1114 /// Ensures a value is in the entry by inserting the default if empty, and returns
1115 /// a mutable reference to the value in the entry.
1116 ///
1117 /// # Examples
1118 ///
1119 /// ```
1120 /// use stable_map::StableMap;
1121 ///
1122 /// let mut map: StableMap<String, u32> = StableMap::new();
1123 ///
1124 /// // nonexistent key
1125 /// map.entry_ref("poneyland").or_insert(3);
1126 /// assert_eq!(map["poneyland"], 3);
1127 ///
1128 /// // existing key
1129 /// *map.entry_ref("poneyland").or_insert(10) *= 2;
1130 /// assert_eq!(map["poneyland"], 6);
1131 /// ```
1132 #[cfg_attr(feature = "inline-more", inline)]
1133 pub fn or_insert(self, value: V) -> &'a mut V
1134 where
1135 K: Hash + From<&'b Q>,
1136 S: BuildHasher,
1137 {
1138 match self {
1139 EntryRef::Occupied(o) => o.into_mut(),
1140 EntryRef::Vacant(v) => v.insert(value),
1141 }
1142 }
1143
1144 /// Ensures a value is in the entry by inserting the result of the default function if empty,
1145 /// and returns a mutable reference to the value in the entry.
1146 ///
1147 /// # Examples
1148 ///
1149 /// ```
1150 /// use stable_map::StableMap;
1151 ///
1152 /// let mut map: StableMap<String, u32> = StableMap::new();
1153 ///
1154 /// // nonexistent key
1155 /// map.entry_ref("poneyland").or_insert_with(|| 3);
1156 /// assert_eq!(map["poneyland"], 3);
1157 ///
1158 /// // existing key
1159 /// *map.entry_ref("poneyland").or_insert_with(|| 10) *= 2;
1160 /// assert_eq!(map["poneyland"], 6);
1161 /// ```
1162 #[cfg_attr(feature = "inline-more", inline)]
1163 pub fn or_insert_with<F>(self, f: F) -> &'a mut V
1164 where
1165 K: Hash + From<&'b Q>,
1166 S: BuildHasher,
1167 F: FnOnce() -> V,
1168 {
1169 match self {
1170 EntryRef::Occupied(o) => o.into_mut(),
1171 EntryRef::Vacant(v) => v.insert(f()),
1172 }
1173 }
1174
1175 /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
1176 /// This method allows for generating key-derived values for insertion by providing the default
1177 /// function an access to the borrower form of the key.
1178 ///
1179 /// # Examples
1180 ///
1181 /// ```
1182 /// use stable_map::StableMap;
1183 ///
1184 /// let mut map: StableMap<String, usize> = StableMap::new();
1185 ///
1186 /// // nonexistent key
1187 /// map.entry_ref("poneyland").or_insert_with_key(|key| key.chars().count());
1188 /// assert_eq!(map["poneyland"], 9);
1189 ///
1190 /// // existing key
1191 /// *map.entry_ref("poneyland").or_insert_with_key(|key| key.chars().count() * 10) *= 2;
1192 /// assert_eq!(map["poneyland"], 18);
1193 /// ```
1194 #[cfg_attr(feature = "inline-more", inline)]
1195 pub fn or_insert_with_key<F>(self, f: F) -> &'a mut V
1196 where
1197 K: Hash + From<&'b Q>,
1198 S: BuildHasher,
1199 F: FnOnce(&'b Q) -> V,
1200 {
1201 match self {
1202 EntryRef::Occupied(o) => o.into_mut(),
1203 EntryRef::Vacant(v) => {
1204 let value = f(v.key());
1205 v.insert(value)
1206 }
1207 }
1208 }
1209}
1210
1211impl<K, V, S> Debug for OccupiedEntry<'_, K, V, S>
1212where
1213 K: Debug,
1214 V: Debug,
1215{
1216 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1217 f.debug_struct("OccupiedEntry")
1218 .field("key", self.key())
1219 .field("value", self.get())
1220 .finish()
1221 }
1222}
1223
1224impl<K, V, S> Debug for VacantEntry<'_, K, V, S>
1225where
1226 K: Debug,
1227 V: Debug,
1228{
1229 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1230 f.debug_tuple("VacantEntry").field(self.key()).finish()
1231 }
1232}
1233
1234impl<K, Q, V, S> Debug for VacantEntryRef<'_, '_, K, Q, V, S>
1235where
1236 Q: Debug,
1237 V: Debug,
1238{
1239 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1240 f.debug_tuple("VacantEntryRef").field(self.key()).finish()
1241 }
1242}
1243
1244impl<K, V, S> Debug for Entry<'_, K, V, S>
1245where
1246 K: Debug,
1247 V: Debug,
1248{
1249 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1250 match *self {
1251 Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
1252 Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
1253 }
1254 }
1255}
1256
1257impl<K, Q, V, S> Debug for EntryRef<'_, '_, K, Q, V, S>
1258where
1259 Q: Debug,
1260 K: Debug,
1261 V: Debug,
1262{
1263 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1264 match *self {
1265 EntryRef::Vacant(ref v) => f.debug_tuple("EntryRef").field(v).finish(),
1266 EntryRef::Occupied(ref o) => f.debug_tuple("EntryRef").field(o).finish(),
1267 }
1268 }
1269}
1270
1271// SAFETY:
1272// - This impl is required because Pos<InUse>, Pos<Stored> allow for conflicting access
1273// but this API prevents this.
1274unsafe impl<K, V, S> Send for OccupiedEntry<'_, K, V, S>
1275where
1276 K: Send,
1277 V: Send,
1278 S: Send,
1279{
1280}
1281
1282// SAFETY:
1283// - This impl is required because Pos<InUse>, Pos<Stored> allow for conflicting access
1284// but this API prevents this.
1285unsafe impl<K, V, S> Sync for OccupiedEntry<'_, K, V, S>
1286where
1287 K: Sync,
1288 V: Sync,
1289 S: Sync,
1290{
1291}
1292
1293// SAFETY:
1294// - This impl is required because Pos<InUse>, Pos<Stored> allow for conflicting access
1295// but this API prevents this.
1296unsafe impl<K, V, S> Send for VacantEntry<'_, K, V, S>
1297where
1298 K: Send,
1299 V: Send,
1300 S: Send,
1301{
1302}
1303
1304// SAFETY:
1305// - This impl is required because Pos<InUse>, Pos<Stored> allow for conflicting access
1306// but this API prevents this.
1307unsafe impl<K, V, S> Sync for VacantEntry<'_, K, V, S>
1308where
1309 K: Sync,
1310 V: Sync,
1311 S: Sync,
1312{
1313}
1314
1315// SAFETY:
1316// - This impl is required because Pos<InUse>, Pos<Stored> allow for conflicting access
1317// but this API prevents this.
1318unsafe impl<K, Q, V, S> Send for VacantEntryRef<'_, '_, K, Q, V, S>
1319where
1320 Q: Send,
1321 K: Send,
1322 V: Send,
1323 S: Send,
1324{
1325}
1326
1327// SAFETY:
1328// - This impl is required because Pos<InUse>, Pos<Stored> allow for conflicting access
1329// but this API prevents this.
1330unsafe impl<K, Q, V, S> Sync for VacantEntryRef<'_, '_, K, Q, V, S>
1331where
1332 Q: Sync,
1333 K: Sync,
1334 V: Sync,
1335 S: Sync,
1336{
1337}