Skip to main content

small_ord_set/
entry.rs

1use std::fmt::{self, Debug};
2
3use smallvec::Array;
4
5use crate::{KeyValuePair, SmallOrdSet};
6
7/// A view into a single entry in a set, which may either be vacant or occupied.
8///
9/// This `enum` is constructed from the [`entry`] method on [`SmallOrdSet`].
10///
11/// [`SmallOrdSet`]: struct.SmallOrdSet.html
12/// [`entry`]: struct.SmallOrdSet.html#method.entry
13pub enum Entry<'a, A: Array, K> {
14    /// An occupied entry.
15    Occupied(OccupiedEntry<'a, A>),
16    /// A vacant entry.
17    Vacant(VacantEntry<'a, A, K>),
18}
19
20/// A view into an occupied entry in a `SmallOrdSet`.
21/// It is part of the [`Entry`] enum.
22///
23/// [`Entry`]: enum.Entry.html
24pub struct OccupiedEntry<'a, A: Array> {
25    set: &'a mut SmallOrdSet<A>,
26    idx: usize,
27}
28
29/// A view into a vacant entry in a `HashMap`.
30/// It is part of the [`Entry`] enum.
31///
32/// [`Entry`]: enum.Entry.html
33pub struct VacantEntry<'a, A: Array, K> {
34    set: &'a mut SmallOrdSet<A>,
35    idx: usize,
36    key: K,
37}
38
39impl<'a, A: Array, K> Entry<'a, A, K> {
40    pub(crate) fn occupied(set: &'a mut SmallOrdSet<A>, idx: usize) -> Self {
41        Entry::Occupied(OccupiedEntry { set, idx })
42    }
43
44    pub(crate) fn vacant(set: &'a mut SmallOrdSet<A>, idx: usize, key: K) -> Self {
45        Entry::Vacant(VacantEntry { set, idx, key })
46    }
47}
48
49impl<'a, A, K, V> Entry<'a, A, K>
50where
51    A: Array<Item = KeyValuePair<K, V>>,
52    K: Ord + 'a,
53    V: 'a,
54{
55    /// Ensures a value is in the entry by inserting the default if empty, and returns
56    /// a mutable reference to the value in the entry.
57    pub fn or_insert(self, default: V) -> &'a mut V {
58        match self {
59            Entry::Occupied(entry) => entry.into_mut(),
60            Entry::Vacant(entry) => entry.insert(default),
61        }
62    }
63
64    /// Ensures a value is in the entry by inserting the result of the default function if empty,
65    /// and returns a mutable reference to the value in the entry.
66    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
67        match self {
68            Entry::Occupied(entry) => entry.into_mut(),
69            Entry::Vacant(entry) => entry.insert(default()),
70        }
71    }
72
73    /// Returns a reference to this entry's key.
74    pub fn key(&self) -> &K {
75        match self {
76            Entry::Occupied(entry) => entry.key(),
77            Entry::Vacant(entry) => entry.key(),
78        }
79    }
80
81    /// Provides in-place mutable access to an occupied entry before any
82    /// potential inserts into the map.
83    pub fn and_modify<F>(self, f: F) -> Self
84    where
85        F: FnOnce(&mut V),
86    {
87        match self {
88            Entry::Occupied(mut entry) => {
89                f(entry.get_mut());
90                Entry::Occupied(entry)
91            }
92            Entry::Vacant(entry) => Entry::Vacant(entry),
93        }
94    }
95}
96
97impl<'a, A> OccupiedEntry<'a, A>
98where
99    A: Array,
100{
101    /// Gets a reference to the the entry.
102    pub fn get_entry(&self) -> &A::Item {
103        &self.set.vec[self.idx]
104    }
105
106    /// Take the ownership of the element from the set.
107    pub fn remove_entry(self) -> A::Item {
108        self.set.vec.remove(self.idx)
109    }
110}
111
112impl<'a, A, K, V> OccupiedEntry<'a, A>
113where
114    A: Array<Item = KeyValuePair<K, V>>,
115    K: Ord + 'a,
116    V: 'a,
117{
118    /// Gets a reference to the key in the entry.
119    pub fn key(&self) -> &K {
120        &self.get_entry().key
121    }
122
123    /// Gets a reference to the value in the entry.
124    pub fn get(&self) -> &V {
125        &self.get_entry().value
126    }
127
128    /// Gets a mutable reference to the value in the entry.
129    ///
130    /// If you need a reference to the `OccupiedEntry` which may outlive the
131    /// destruction of the `Entry` value, see [`into_mut`].
132    ///
133    /// [`into_mut`]: #method.into_mut
134    pub fn get_mut(&mut self) -> &mut V {
135        &mut self.set.vec[self.idx].value
136    }
137
138    /// Converts the OccupiedEntry into a mutable reference to the value in the entry
139    /// with a lifetime bound to the map itself.
140    ///
141    /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
142    ///
143    /// [`get_mut`]: #method.get_mut
144    pub fn into_mut(self) -> &'a mut V {
145        &mut self.set.vec[self.idx].value
146    }
147}
148
149impl<'a, A: Array, K> VacantEntry<'a, A, K> {
150    /// Gets a reference to the key that would be used when inserting a value through the VacantEntry.
151    pub fn key(&self) -> &K {
152        &self.key
153    }
154
155    /// Take ownership of the key.
156    pub fn into_key(self) -> K {
157        self.key
158    }
159
160    /// Insert an element using the given constructor.
161    ///
162    /// The ordering of the computed element must match that of the key.
163    pub fn insert_with<F>(self, f: F) -> &'a mut A::Item
164    where
165        F: FnOnce(K) -> A::Item,
166    {
167        let element = f(self.key);
168        self.set.vec.insert(self.idx, element);
169        &mut self.set.vec[self.idx]
170    }
171}
172
173impl<'a, A, K, V> VacantEntry<'a, A, K>
174where
175    A: Array<Item = KeyValuePair<K, V>>,
176    K: Ord + 'a,
177    V: 'a,
178{
179    /// Sets the value of the entry with the VacantEntry's key, and returns a mutable reference to it.
180    pub fn insert(self, value: V) -> &'a mut V {
181        &mut self.insert_with(|key| KeyValuePair { key, value }).value
182    }
183}
184
185impl<A, K> Debug for Entry<'_, A, K>
186where
187    A: Array,
188    A::Item: Debug,
189    K: Debug,
190{
191    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
192        match *self {
193            Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
194            Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
195        }
196    }
197}
198
199impl<A> Debug for OccupiedEntry<'_, A>
200where
201    A: Array,
202    A::Item: Debug,
203{
204    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
205        f.debug_struct("OccupiedEntry")
206            .field("element", self.get_entry())
207            .finish()
208    }
209}
210
211impl<A, K> Debug for VacantEntry<'_, A, K>
212where
213    A: Array,
214    K: Debug,
215{
216    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217        f.debug_tuple("VacantEntry").finish()
218    }
219}