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}