btree_slab/generic/map/entry.rs
1use crate::generic::{
2 map::{BTreeExt, BTreeExtMut, BTreeMap},
3 node::{Address, Item, Node},
4};
5use cc_traits::{SimpleCollectionMut, SimpleCollectionRef, Slab, SlabMut};
6use std::fmt;
7
8/// A view into a single entry in a map, which may either be vacant or occupied.
9///
10/// This enum is constructed from the [`entry`](`BTreeMap#entry`) method on [`BTreeMap`].
11pub enum Entry<'a, K, V, C = slab::Slab<Node<K, V>>> {
12 Vacant(VacantEntry<'a, K, V, C>),
13 Occupied(OccupiedEntry<'a, K, V, C>),
14}
15
16use Entry::*;
17
18impl<'a, K, V, C: Slab<Node<K, V>>> Entry<'a, K, V, C>
19where
20 C: SimpleCollectionRef,
21{
22 /// Gets the address of the entry in the B-Tree.
23 #[inline]
24 pub fn address(&self) -> Address {
25 match self {
26 Occupied(entry) => entry.address(),
27 Vacant(entry) => entry.address(),
28 }
29 }
30
31 /// Returns a reference to this entry's key.
32 ///
33 /// # Examples
34 ///
35 /// ```
36 /// use btree_slab::BTreeMap;
37 ///
38 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
39 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
40 /// ```
41 #[inline]
42 pub fn key(&self) -> &K {
43 match *self {
44 Occupied(ref entry) => entry.key(),
45 Vacant(ref entry) => entry.key(),
46 }
47 }
48}
49
50impl<'a, K, V, C: SlabMut<Node<K, V>>> Entry<'a, K, V, C>
51where
52 C: SimpleCollectionRef,
53 C: SimpleCollectionMut,
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 ///
58 /// # Examples
59 ///
60 /// ```
61 /// use btree_slab::BTreeMap;
62 ///
63 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
64 /// map.entry("poneyland").or_insert(12);
65 ///
66 /// assert_eq!(map["poneyland"], 12);
67 /// ```
68 #[inline]
69 pub fn or_insert(self, default: V) -> &'a mut V {
70 match self {
71 Occupied(entry) => entry.into_mut(),
72 Vacant(entry) => entry.insert(default),
73 }
74 }
75
76 /// Ensures a value is in the entry by inserting the result of the default function if empty,
77 /// and returns a mutable reference to the value in the entry.
78 ///
79 /// # Examples
80 ///
81 /// ```
82 /// use btree_slab::BTreeMap;
83 ///
84 /// let mut map: BTreeMap<&str, String> = BTreeMap::new();
85 /// let s = "hoho".to_string();
86 ///
87 /// map.entry("poneyland").or_insert_with(|| s);
88 ///
89 /// assert_eq!(map["poneyland"], "hoho".to_string());
90 /// ```
91 #[inline]
92 pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
93 match self {
94 Occupied(entry) => entry.into_mut(),
95 Vacant(entry) => entry.insert(default()),
96 }
97 }
98
99 /// Ensures a value is in the entry by inserting, if empty, the result of the default function,
100 /// which takes the key as its argument, and returns a mutable reference to the value in the
101 /// entry.
102 ///
103 /// # Examples
104 ///
105 /// ```
106 /// use btree_slab::BTreeMap;
107 ///
108 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
109 ///
110 /// map.entry("poneyland").or_insert_with_key(|key| key.chars().count());
111 ///
112 /// assert_eq!(map["poneyland"], 9);
113 /// ```
114 #[inline]
115 pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V {
116 match self {
117 Occupied(entry) => entry.into_mut(),
118 Vacant(entry) => {
119 let value = default(entry.key());
120 entry.insert(value)
121 }
122 }
123 }
124
125 /// Provides in-place mutable access to an occupied entry before any
126 /// potential inserts into the map.
127 ///
128 /// # Examples
129 ///
130 /// ```
131 /// use btree_slab::BTreeMap;
132 ///
133 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
134 ///
135 /// map.entry("poneyland")
136 /// .and_modify(|e| { *e += 1 })
137 /// .or_insert(42);
138 /// assert_eq!(map["poneyland"], 42);
139 ///
140 /// map.entry("poneyland")
141 /// .and_modify(|e| { *e += 1 })
142 /// .or_insert(42);
143 /// assert_eq!(map["poneyland"], 43);
144 /// ```
145 #[inline]
146 pub fn and_modify<F>(self, f: F) -> Self
147 where
148 F: FnOnce(&mut V),
149 {
150 match self {
151 Occupied(mut entry) => {
152 f(entry.get_mut());
153 Occupied(entry)
154 }
155 Vacant(entry) => Vacant(entry),
156 }
157 }
158
159 /// Ensures a value is in the entry by inserting the default value if empty,
160 /// and returns a mutable reference to the value in the entry.
161 ///
162 /// # Examples
163 ///
164 /// ```
165 /// use btree_slab::BTreeMap;
166 ///
167 /// let mut map: BTreeMap<&str, Option<usize>> = BTreeMap::new();
168 /// map.entry("poneyland").or_default();
169 ///
170 /// assert_eq!(map["poneyland"], None);
171 /// ```
172 #[inline]
173 pub fn or_default(self) -> &'a mut V
174 where
175 V: Default,
176 {
177 match self {
178 Occupied(entry) => entry.into_mut(),
179 Vacant(entry) => entry.insert(Default::default()),
180 }
181 }
182}
183
184impl<'a, K: fmt::Debug, V: fmt::Debug, C: Slab<Node<K, V>>> fmt::Debug for Entry<'a, K, V, C>
185where
186 C: SimpleCollectionRef,
187{
188 #[inline]
189 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
190 match self {
191 Occupied(entry) => entry.fmt(f),
192 Vacant(entry) => entry.fmt(f),
193 }
194 }
195}
196
197/// A view into a vacant entry in a [`BTreeMap`].
198/// It is part of the [`Entry`] enum.
199pub struct VacantEntry<'a, K, V, C = slab::Slab<Node<K, V>>> {
200 pub(crate) map: &'a mut BTreeMap<K, V, C>,
201 pub(crate) key: K,
202 pub(crate) addr: Address,
203}
204
205impl<'a, K, V, C: Slab<Node<K, V>>> VacantEntry<'a, K, V, C> {
206 /// Gets the address of the vacant entry in the B-Tree.
207 #[inline]
208 pub fn address(&self) -> Address {
209 self.addr
210 }
211
212 /// Gets a reference to the keys that would be used when inserting a value through the `VacantEntry`.
213 ///
214 /// ## Example
215 /// ```
216 /// use btree_slab::BTreeMap;
217 ///
218 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
219 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
220 /// ```
221 #[inline]
222 pub fn key(&self) -> &K {
223 &self.key
224 }
225
226 /// Take ownership of the key.
227 ///
228 /// ## Example
229 /// ```
230 /// use btree_slab::BTreeMap;
231 /// use btree_slab::generic::map::Entry;
232 ///
233 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
234 ///
235 /// if let Entry::Vacant(v) = map.entry("poneyland") {
236 /// v.into_key();
237 /// }
238 /// ```
239 #[inline]
240 pub fn into_key(self) -> K {
241 self.key
242 }
243}
244
245impl<'a, K, V, C: SlabMut<Node<K, V>>> VacantEntry<'a, K, V, C>
246where
247 C: SimpleCollectionRef,
248 C: SimpleCollectionMut,
249{
250 /// Sets the value of the entry with the `VacantEntry`'s key,
251 /// and returns a mutable reference to it.
252 ///
253 /// ## Example
254 /// ```
255 /// use btree_slab::BTreeMap;
256 /// use btree_slab::generic::map::Entry;
257 ///
258 /// let mut map: BTreeMap<&str, u32> = BTreeMap::new();
259 ///
260 /// if let Entry::Vacant(o) = map.entry("poneyland") {
261 /// o.insert(37);
262 /// }
263 /// assert_eq!(map["poneyland"], 37);
264 /// ```
265 #[inline]
266 pub fn insert(self, value: V) -> &'a mut V {
267 let addr = self.map.insert_at(self.addr, Item::new(self.key, value));
268 self.map.item_mut(addr).unwrap().value_mut()
269 }
270}
271
272impl<'a, K: fmt::Debug, V, C: Slab<Node<K, V>>> fmt::Debug for VacantEntry<'a, K, V, C> {
273 #[inline]
274 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
275 f.debug_tuple("VacantEntry").field(self.key()).finish()
276 }
277}
278
279/// A view into an occupied entry in a [`BTreeMap`].
280/// It is part of the [`Entry`] enum.
281pub struct OccupiedEntry<'a, K, V, C = slab::Slab<Node<K, V>>> {
282 pub(crate) map: &'a mut BTreeMap<K, V, C>,
283 pub(crate) addr: Address,
284}
285
286impl<'a, K, V, C: Slab<Node<K, V>>> OccupiedEntry<'a, K, V, C>
287where
288 C: SimpleCollectionRef,
289{
290 /// Gets the address of the occupied entry in the B-Tree.
291 #[inline]
292 pub fn address(&self) -> Address {
293 self.addr
294 }
295
296 /// Gets a reference to the value in the entry.
297 ///
298 /// # Example
299 /// ```
300 /// use btree_slab::BTreeMap;
301 /// use btree_slab::generic::map::Entry;
302 ///
303 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
304 /// map.entry("poneyland").or_insert(12);
305 ///
306 /// if let Entry::Occupied(o) = map.entry("poneyland") {
307 /// assert_eq!(o.get(), &12);
308 /// }
309 /// ```
310 #[inline]
311 pub fn get(&self) -> &V {
312 self.map.item(self.addr).unwrap().value()
313 }
314
315 /// Gets a reference to the key in the entry.
316 ///
317 /// # Example
318 /// ```
319 /// use btree_slab::BTreeMap;
320 ///
321 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
322 /// map.entry("poneyland").or_insert(12);
323 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
324 /// ```
325 #[inline]
326 pub fn key(&self) -> &K {
327 self.map.item(self.addr).unwrap().key()
328 }
329}
330
331impl<'a, K, V, C: SlabMut<Node<K, V>>> OccupiedEntry<'a, K, V, C>
332where
333 C: SimpleCollectionRef,
334 C: SimpleCollectionMut,
335{
336 /// Gets a mutable reference to the value in the entry.
337 ///
338 /// If you need a reference to the OccupiedEntry that may outlive
339 /// the destruction of the Entry value, see into_mut.
340 ///
341 /// # Example
342 /// ```
343 /// use btree_slab::BTreeMap;
344 /// use btree_slab::generic::map::Entry;
345 ///
346 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
347 /// map.entry("poneyland").or_insert(12);
348 ///
349 /// assert_eq!(map["poneyland"], 12);
350 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
351 /// *o.get_mut() += 10;
352 /// assert_eq!(*o.get(), 22);
353 ///
354 /// // We can use the same Entry multiple times.
355 /// *o.get_mut() += 2;
356 /// }
357 /// assert_eq!(map["poneyland"], 24);
358 /// ```
359 #[inline]
360 pub fn get_mut(&mut self) -> &mut V {
361 self.map.item_mut(self.addr).unwrap().value_mut()
362 }
363
364 /// Sets the value of the entry with the OccupiedEntry's key,
365 /// and returns the entry's old value.
366 ///
367 /// # Example
368 /// ```
369 /// use btree_slab::BTreeMap;
370 /// use btree_slab::generic::map::Entry;
371 ///
372 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
373 /// map.entry("poneyland").or_insert(12);
374 ///
375 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
376 /// assert_eq!(o.insert(15), 12);
377 /// }
378 /// assert_eq!(map["poneyland"], 15);
379 /// ```
380 #[inline]
381 pub fn insert(&mut self, value: V) -> V {
382 self.map.item_mut(self.addr).unwrap().set_value(value)
383 }
384
385 /// Converts the entry into a mutable reference to its value.
386 ///
387 /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
388 ///
389 /// [`get_mut`]: #method.get_mut
390 ///
391 /// # Example
392 ///
393 /// ```
394 /// use btree_slab::BTreeMap;
395 /// use btree_slab::generic::map::Entry;
396 ///
397 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
398 /// map.entry("poneyland").or_insert(12);
399 ///
400 /// assert_eq!(map["poneyland"], 12);
401 /// if let Entry::Occupied(o) = map.entry("poneyland") {
402 /// *o.into_mut() += 10;
403 /// }
404 /// assert_eq!(map["poneyland"], 22);
405 /// ```
406 #[inline]
407 pub fn into_mut(self) -> &'a mut V {
408 self.map.item_mut(self.addr).unwrap().value_mut()
409 }
410
411 /// Takes the value of the entry out of the map, and returns it.
412 ///
413 /// # Examples
414 ///
415 /// ```
416 /// use btree_slab::BTreeMap;
417 /// use btree_slab::generic::map::Entry;
418 ///
419 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
420 /// map.entry("poneyland").or_insert(12);
421 ///
422 /// if let Entry::Occupied(o) = map.entry("poneyland") {
423 /// assert_eq!(o.remove(), 12);
424 /// }
425 /// // If we try to get "poneyland"'s value, it'll panic:
426 /// // println!("{}", map["poneyland"]);
427 /// ```
428 #[inline]
429 pub fn remove(self) -> V {
430 self.map.remove_at(self.addr).unwrap().0.into_value()
431 }
432
433 /// Take ownership of the key and value from the map.
434 ///
435 /// # Example
436 /// ```
437 /// use btree_slab::BTreeMap;
438 /// use btree_slab::generic::map::Entry;
439 ///
440 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
441 /// map.entry("poneyland").or_insert(12);
442 ///
443 /// if let Entry::Occupied(o) = map.entry("poneyland") {
444 /// // We delete the entry from the map.
445 /// o.remove_entry();
446 /// }
447 ///
448 /// // If now try to get the value, it will panic:
449 /// // println!("{}", map["poneyland"]);
450 /// ```
451 #[inline]
452 pub fn remove_entry(self) -> (K, V) {
453 self.map.remove_at(self.addr).unwrap().0.into_pair()
454 }
455}
456
457impl<'a, K: fmt::Debug, V: fmt::Debug, C: Slab<Node<K, V>>> fmt::Debug
458 for OccupiedEntry<'a, K, V, C>
459where
460 C: SimpleCollectionRef,
461{
462 #[inline]
463 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
464 f.debug_struct("OccupiedEntry")
465 .field("key", self.key())
466 .field("value", self.get())
467 .finish()
468 }
469}