hextree/entry.rs
1//! `HexTreeMap`'s Entry API.
2
3use crate::{compaction::Compactor, Cell, HexTreeMap};
4
5/// A view into a single entry in a map, which may either be vacant or
6/// occupied.
7///
8/// This enum is constructed from the [entry][HexTreeMap::entry]
9/// method on [HexTreeMap][HexTreeMap].
10pub enum Entry<'a, V, C> {
11 /// An occupied entry.
12 Occupied(OccupiedEntry<'a, V>),
13 /// A vacant entry.
14 Vacant(VacantEntry<'a, V, C>),
15}
16
17/// A view into an occupied entry in a `HexTreeMap`. It is part of the
18/// [`Entry`] enum.
19pub struct OccupiedEntry<'a, V> {
20 pub(crate) target_cell: Cell,
21 pub(crate) cell_value: (Cell, &'a mut V),
22}
23
24/// A view into a vacant entry in a `HexTreeMap`. It is part of the
25/// [`Entry`] enum.
26pub struct VacantEntry<'a, V, C> {
27 pub(crate) target_cell: Cell,
28 pub(crate) map: &'a mut HexTreeMap<V, C>,
29}
30
31impl<'a, V, C> Entry<'a, V, C>
32where
33 C: Compactor<V>,
34{
35 /// Provides in-place mutable access to an occupied entry before
36 /// any potential inserts into the map.
37 ///
38 /// # Examples
39 ///
40 /// ```
41 /// # fn main() -> hextree::Result<()> {;
42 /// use hextree::{Cell, HexTreeMap};
43 ///
44 /// let mut map = HexTreeMap::new();
45 /// let eiffel_tower_res12 = Cell::from_raw(0x8c1fb46741ae9ff)?;
46 ///
47 /// map.entry(eiffel_tower_res12)
48 /// .and_modify(|_actual_cell, v| *v = "Paris")
49 /// .or_insert("France");
50 /// assert_eq!(map[eiffel_tower_res12], "France");
51 ///
52 /// map.entry(eiffel_tower_res12)
53 /// .and_modify(|_actual_cell, v| *v = "Paris")
54 /// .or_insert("France");
55 /// assert_eq!(map[eiffel_tower_res12], "Paris");
56 /// # Ok(())
57 /// # }
58 /// ```
59 pub fn and_modify<F>(self, f: F) -> Self
60 where
61 F: FnOnce(Cell, &mut V),
62 {
63 match self {
64 Entry::Occupied(OccupiedEntry {
65 target_cell,
66 cell_value: (cell, value),
67 }) => {
68 f(cell, value);
69 Entry::Occupied(OccupiedEntry {
70 target_cell,
71 cell_value: (cell, value),
72 })
73 }
74 Entry::Vacant(_) => self,
75 }
76 }
77
78 /// Ensures a value is in the entry by inserting the default if
79 /// empty, and returns a mutable reference to the value in the
80 /// entry.
81 ///
82 /// # Examples
83 ///
84 /// ```
85 /// # fn main() -> hextree::Result<()> {;
86 /// use hextree::{Cell, HexTreeMap};
87 ///
88 /// let mut map = HexTreeMap::new();
89 /// let eiffel_tower_res12 = Cell::from_raw(0x8c1fb46741ae9ff)?;
90 ///
91 /// map.entry(eiffel_tower_res12)
92 /// .or_insert("Paris");
93 /// assert_eq!(map[eiffel_tower_res12], "Paris");
94 /// # Ok(())
95 /// # }
96 /// ```
97 pub fn or_insert(self, default: V) -> (Cell, &'a mut V) {
98 match self {
99 Entry::Occupied(OccupiedEntry {
100 target_cell: _,
101 cell_value,
102 }) => cell_value,
103 Entry::Vacant(VacantEntry { target_cell, map }) => {
104 map.insert(target_cell, default);
105 // We just inserted; unwrap is fine.
106 map.get_mut(target_cell).unwrap()
107 }
108 }
109 }
110
111 /// Ensures a value is in the entry by inserting the result of the
112 /// default function if empty, and returns a mutable reference to
113 /// the value in the entry.
114 ///
115 /// # Examples
116 ///
117 /// ```
118 /// # fn main() -> hextree::Result<()> {;
119 /// use hextree::{Cell, HexTreeMap};
120 ///
121 /// let mut map = HexTreeMap::new();
122 /// let eiffel_tower_res12 = Cell::from_raw(0x8c1fb46741ae9ff)?;
123 ///
124 /// map.entry(eiffel_tower_res12)
125 /// .or_insert_with(|| "Paris");
126 /// assert_eq!(map[eiffel_tower_res12], "Paris");
127 /// # Ok(())
128 /// # }
129 /// ```
130 pub fn or_insert_with<F>(self, default: F) -> (Cell, &'a mut V)
131 where
132 F: FnOnce() -> V,
133 {
134 match self {
135 Entry::Occupied(OccupiedEntry {
136 target_cell: _,
137 cell_value,
138 }) => cell_value,
139 Entry::Vacant(VacantEntry { target_cell, map }) => {
140 map.insert(target_cell, default());
141 // We just inserted; unwrap is fine.
142 map.get_mut(target_cell).unwrap()
143 }
144 }
145 }
146}
147
148impl<'a, V, C> Entry<'a, V, C>
149where
150 V: Default,
151 C: Compactor<V>,
152{
153 /// Ensures a value is in the entry by inserting the default value
154 /// if empty, and returns a mutable reference to the value in the
155 /// entry.
156 ///
157 /// # Examples
158 ///
159 /// ```
160 /// # fn main() -> hextree::Result<()> {
161 /// use hextree::{Cell, HexTreeMap};
162 ///
163 /// let mut map: HexTreeMap<Option<&str>> = HexTreeMap::new();
164 /// let eiffel_tower_res12 = Cell::from_raw(0x8c1fb46741ae9ff)?;
165 ///
166 /// map.entry(eiffel_tower_res12).or_default();
167 /// assert_eq!(map[eiffel_tower_res12], None);
168 /// # Ok(())
169 /// # }
170 /// ```
171 pub fn or_default(self) -> (Cell, &'a mut V) {
172 match self {
173 Entry::Occupied(OccupiedEntry {
174 target_cell: _,
175 cell_value,
176 }) => cell_value,
177 Entry::Vacant(VacantEntry { target_cell, map }) => {
178 map.insert(target_cell, Default::default());
179 map.get_mut(target_cell).expect("we just inserted")
180 }
181 }
182 }
183}