1use core::hash::{BuildHasher, Hash};
2
3use super::{Bucket, Entries, Equivalent, IndexMap};
4
5/// Opt-in mutable access to keys.
6///
7/// These methods expose `&mut K`, mutable references to the key as it is stored
8/// in the map.
9/// You are allowed to modify the keys in the hashmap **if the modification
10/// does not change the key’s hash and equality**.
11///
12/// If keys are modified erroneously, you can no longer look them up.
13/// This is sound (memory safe) but a logical error hazard (just like
14/// implementing PartialEq, Eq, or Hash incorrectly would be).
15///
16/// `use` this trait to enable its methods for `IndexMap`.
17///
18/// This trait is sealed and cannot be implemented for types outside this crate.
19pub trait MutableKeys: private::Sealed {
20 type Key;
21 type Value;
22
23 /// Return item index, mutable reference to key and value
24 ///
25 /// Computes in **O(1)** time (average).
26 fn get_full_mut2<Q: ?Sized>(
27 &mut self,
28 key: &Q,
29 ) -> Option<(usize, &mut Self::Key, &mut Self::Value)>
30 where
31 Q: Hash + Equivalent<Self::Key>;
32
33 /// Return mutable reference to key and value at an index.
34 ///
35 /// Valid indices are *0 <= index < self.len()*
36 ///
37 /// Computes in **O(1)** time.
38 fn get_index_mut2(&mut self, index: usize) -> Option<(&mut Self::Key, &mut Self::Value)>;
39
40 /// Scan through each key-value pair in the map and keep those where the
41 /// closure `keep` returns `true`.
42 ///
43 /// The elements are visited in order, and remaining elements keep their
44 /// order.
45 ///
46 /// Computes in **O(n)** time (average).
47 fn retain2<F>(&mut self, keep: F)
48 where
49 F: FnMut(&mut Self::Key, &mut Self::Value) -> bool;
50}
51
52/// Opt-in mutable access to keys.
53///
54/// See [`MutableKeys`](trait.MutableKeys.html) for more information.
55impl<K, V, S> MutableKeys for IndexMap<K, V, S>
56where
57 K: Eq + Hash,
58 S: BuildHasher,
59{
60 type Key = K;
61 type Value = V;
62
63 fn get_full_mut2<Q: ?Sized>(&mut self, key: &Q) -> Option<(usize, &mut K, &mut V)>
64 where
65 Q: Hash + Equivalent<K>,
66 {
67 if let Some(i) = self.get_index_of(key) {
68 let entry = &mut self.as_entries_mut()[i];
69 Some((i, &mut entry.key, &mut entry.value))
70 } else {
71 None
72 }
73 }
74
75 fn get_index_mut2(&mut self, index: usize) -> Option<(&mut K, &mut V)> {
76 self.as_entries_mut().get_mut(index).map(Bucket::muts)
77 }
78
79 fn retain2<F>(&mut self, keep: F)
80 where
81 F: FnMut(&mut K, &mut V) -> bool,
82 {
83 self.retain_mut(keep)
84 }
85}
86
87mod private {
88 pub trait Sealed {}
89
90 impl<K, V, S> Sealed for super::IndexMap<K, V, S> {}
91}
92