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}