prefix_trie/map/
entry.rs

1//! Code for inserting elements and the entry pattern.
2
3use super::*;
4
5/// A mutable view into a single entry in a map, which may either be vacant or occupied.
6pub enum Entry<'a, P, T> {
7    /// The entry is not present in the tree.
8    Vacant(VacantEntry<'a, P, T>),
9    /// The entry is already present in the tree.
10    Occupied(OccupiedEntry<'a, P, T>),
11}
12
13/// A mutable view into a missing entry. The information within this structure describes a path
14/// towards that missing node, and how to insert it.
15pub struct VacantEntry<'a, P, T> {
16    pub(super) map: &'a mut PrefixMap<P, T>,
17    pub(super) prefix: P,
18    pub(super) idx: usize,
19    pub(super) direction: DirectionForInsert<P>,
20}
21
22/// A mutable view into an occupied entry. An occupied entry represents a node that is already
23/// present on the tree.
24pub struct OccupiedEntry<'a, P, T> {
25    pub(crate) node: &'a mut Node<P, T>,
26    pub(super) prefix: P, // needed to replace the prefix on the thing if we perform insert.
27}
28
29impl<P, T> Entry<'_, P, T> {
30    /// Get the value if it exists
31    ///
32    /// ```
33    /// # use prefix_trie::*;
34    /// # #[cfg(feature = "ipnet")]
35    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
36    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
37    /// pm.insert("192.168.1.0/24".parse()?, 1);
38    /// assert_eq!(pm.entry("192.168.1.0/24".parse()?).get(), Some(&1));
39    /// assert_eq!(pm.entry("192.168.2.0/24".parse()?).get(), None);
40    /// # Ok(())
41    /// # }
42    /// # #[cfg(not(feature = "ipnet"))]
43    /// # fn main() {}
44    /// ```
45    pub fn get(&self) -> Option<&T> {
46        match self {
47            Entry::Vacant(_) => None,
48            Entry::Occupied(e) => e.node.value.as_ref(),
49        }
50    }
51
52    /// Get the value if it exists
53    ///
54    /// ```
55    /// # use prefix_trie::*;
56    /// # #[cfg(feature = "ipnet")]
57    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
58    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
59    /// pm.insert("192.168.1.0/24".parse()?, 1);
60    /// pm.entry("192.168.1.0/24".parse()?).get_mut().map(|x| *x += 1);
61    /// pm.entry("192.168.2.0/24".parse()?).get_mut().map(|x| *x += 1);
62    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), Some(&2));
63    /// assert_eq!(pm.get(&"192.168.2.0/24".parse()?), None);
64    /// # Ok(())
65    /// # }
66    /// # #[cfg(not(feature = "ipnet"))]
67    /// # fn main() {}
68    /// ```
69    pub fn get_mut(&mut self) -> Option<&mut T> {
70        match self {
71            Entry::Vacant(_) => None,
72            Entry::Occupied(e) => e.node.value.as_mut(),
73        }
74    }
75
76    /// get the key of the current entry
77    ///
78    /// ```
79    /// # use prefix_trie::*;
80    /// # #[cfg(feature = "ipnet")]
81    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
82    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
83    /// pm.insert("192.168.1.0/24".parse()?, 1);
84    /// assert_eq!(pm.entry("192.168.1.0/24".parse()?).key(), &"192.168.1.0/24".parse()?);
85    /// assert_eq!(pm.entry("192.168.2.0/24".parse()?).key(), &"192.168.2.0/24".parse()?);
86    /// # Ok(())
87    /// # }
88    /// # #[cfg(not(feature = "ipnet"))]
89    /// # fn main() {}
90    /// ```
91    pub fn key(&self) -> &P {
92        match self {
93            Entry::Vacant(e) => &e.prefix,
94            Entry::Occupied(e) => &e.node.prefix,
95        }
96    }
97}
98
99impl<'a, P, T> Entry<'a, P, T>
100where
101    P: Prefix,
102{
103    /// Replace the current entry, and return the entry that was stored before. This will also
104    /// replace the key with the one provided to the `entry` function.
105    ///
106    /// ```
107    /// # use prefix_trie::*;
108    /// # #[cfg(feature = "ipnet")]
109    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
110    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
111    /// pm.insert("192.168.1.0/24".parse()?, 1);
112    ///
113    /// assert_eq!(pm.entry("192.168.1.0/24".parse()?).insert(10), Some(1));
114    /// assert_eq!(pm.entry("192.168.2.0/24".parse()?).insert(20), None);
115    ///
116    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), Some(&10));
117    /// assert_eq!(pm.get(&"192.168.2.0/24".parse()?), Some(&20));
118    /// # Ok(())
119    /// # }
120    /// # #[cfg(not(feature = "ipnet"))]
121    /// # fn main() {}
122    /// ```
123    ///
124    /// This function *will replace* the prefix in the map with the one provided to the `entry` call:
125    ///
126    /// ```
127    /// # use prefix_trie::*;
128    /// # #[cfg(feature = "ipnet")]
129    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
130    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
131    /// pm.insert("192.168.1.1/24".parse()?, 1);
132    /// pm.entry("192.168.1.2/24".parse()?).insert(2);
133    /// assert_eq!(
134    ///     pm.get_key_value(&"192.168.1.0/24".parse()?),
135    ///     Some((&"192.168.1.2/24".parse()?, &2)) // prefix is overwritten
136    /// );
137    /// # Ok(())
138    /// # }
139    /// # #[cfg(not(feature = "ipnet"))]
140    /// # fn main() {}
141    /// ```
142    #[inline(always)]
143    pub fn insert(self, v: T) -> Option<T> {
144        match self {
145            Entry::Vacant(e) => {
146                e._insert(v);
147                None
148            }
149            Entry::Occupied(e) => Some(e.insert(v)),
150        }
151    }
152
153    /// Ensures a value is in the entry by inserting the default if empty, and returns a mutable
154    /// reference to the value in the entry.
155    ///
156    /// ```
157    /// # use prefix_trie::*;
158    /// # #[cfg(feature = "ipnet")]
159    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
160    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
161    /// pm.insert("192.168.1.0/24".parse()?, 1);
162    ///
163    /// assert_eq!(pm.entry("192.168.1.0/24".parse()?).or_insert(10), &1);
164    /// assert_eq!(pm.entry("192.168.2.0/24".parse()?).or_insert(20), &20);
165    ///
166    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), Some(&1));
167    /// assert_eq!(pm.get(&"192.168.2.0/24".parse()?), Some(&20));
168    /// # Ok(())
169    /// # }
170    /// # #[cfg(not(feature = "ipnet"))]
171    /// # fn main() {}
172    /// ```
173    ///
174    /// This function will *not* replace the prefix in the map if it already exists.
175    ///
176    /// ```
177    /// # use prefix_trie::*;
178    /// # #[cfg(feature = "ipnet")]
179    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
180    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
181    /// pm.insert("192.168.1.1/24".parse()?, 1);
182    /// pm.entry("192.168.1.2/24".parse()?).or_insert(2);
183    /// assert_eq!(
184    ///     pm.get_key_value(&"192.168.1.0/24".parse()?),
185    ///     Some((&"192.168.1.1/24".parse()?, &1)) // prefix is not overwritten.
186    /// );
187    /// # Ok(())
188    /// # }
189    /// # #[cfg(not(feature = "ipnet"))]
190    /// # fn main() {}
191    /// ```
192    #[inline(always)]
193    pub fn or_insert(self, default: T) -> &'a mut T {
194        match self {
195            Entry::Vacant(e) => e._insert(default).value.as_mut().unwrap(),
196            Entry::Occupied(e) => e.node.value.get_or_insert(default),
197        }
198    }
199
200    /// Ensures a value is in the entry by inserting the result of the default function if empty,
201    /// and returns a mutable reference to the value in the entry.
202    ///
203    /// ```
204    /// # use prefix_trie::*;
205    /// # #[cfg(feature = "ipnet")]
206    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
207    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
208    /// pm.insert("192.168.1.0/24".parse()?, 1);
209    ///
210    /// assert_eq!(pm.entry("192.168.1.0/24".parse()?).or_insert_with(|| 10), &1);
211    /// assert_eq!(pm.entry("192.168.2.0/24".parse()?).or_insert_with(|| 20), &20);
212    ///
213    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), Some(&1));
214    /// assert_eq!(pm.get(&"192.168.2.0/24".parse()?), Some(&20));
215    /// # Ok(())
216    /// # }
217    /// # #[cfg(not(feature = "ipnet"))]
218    /// # fn main() {}
219    /// ```
220    ///
221    /// This function will *not* replace the prefix in the map if it already exists.
222    ///
223    /// ```
224    /// # use prefix_trie::*;
225    /// # #[cfg(feature = "ipnet")]
226    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
227    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
228    /// pm.insert("192.168.1.1/24".parse()?, 1);
229    /// pm.entry("192.168.1.2/24".parse()?).or_insert_with(|| 2);
230    /// assert_eq!(
231    ///     pm.get_key_value(&"192.168.1.0/24".parse()?),
232    ///     Some((&"192.168.1.1/24".parse()?, &1)) // prefix is not overwritten.
233    /// );
234    /// # Ok(())
235    /// # }
236    /// # #[cfg(not(feature = "ipnet"))]
237    /// # fn main() {}
238    /// ```
239    #[inline(always)]
240    pub fn or_insert_with<F: FnOnce() -> T>(self, default: F) -> &'a mut T {
241        match self {
242            Entry::Vacant(e) => e._insert(default()).value.as_mut().unwrap(),
243            Entry::Occupied(e) => e.node.value.get_or_insert_with(default),
244        }
245    }
246
247    /// Provides in-place mutable access to an occupied entry before any potential inserts into the
248    /// map.
249    ///
250    /// ```
251    /// # use prefix_trie::*;
252    /// # #[cfg(feature = "ipnet")]
253    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
254    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
255    /// pm.insert("192.168.1.0/24".parse()?, 1);
256    /// assert_eq!(pm.entry("192.168.1.0/24".parse()?).and_modify(|x| *x += 1).get(), Some(&2));
257    /// assert_eq!(pm.entry("192.168.2.0/24".parse()?).and_modify(|x| *x += 1).get(), None);
258    /// # Ok(())
259    /// # }
260    /// # #[cfg(not(feature = "ipnet"))]
261    /// # fn main() {}
262    /// ```
263    ///
264    /// This function will *not* replace the prefix in the map if it already exists.
265    ///
266    /// ```
267    /// # use prefix_trie::*;
268    /// # #[cfg(feature = "ipnet")]
269    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
270    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
271    /// pm.insert("192.168.1.1/24".parse()?, 1);
272    /// pm.entry("192.168.1.2/24".parse()?).and_modify(|x| *x += 1);
273    /// assert_eq!(
274    ///     pm.get_key_value(&"192.168.1.0/24".parse()?),
275    ///     Some((&"192.168.1.1/24".parse()?, &2)) // prefix is not overwritten.
276    /// );
277    /// # Ok(())
278    /// # }
279    /// # #[cfg(not(feature = "ipnet"))]
280    /// # fn main() {}
281    /// ```
282    #[inline(always)]
283    pub fn and_modify<F: FnOnce(&mut T)>(self, f: F) -> Self {
284        match self {
285            Entry::Vacant(e) => Entry::Vacant(e),
286            Entry::Occupied(e) => {
287                e.node.value.as_mut().map(f);
288                Entry::Occupied(e)
289            }
290        }
291    }
292}
293
294impl<'a, P, T> Entry<'a, P, T>
295where
296    P: Prefix,
297    T: Default,
298{
299    /// Ensures a value is in the entry by inserting the default value if empty, and returns a
300    /// mutable reference to the value in the entry.
301    ///
302    /// ```
303    /// # use prefix_trie::*;
304    /// # #[cfg(feature = "ipnet")]
305    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
306    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
307    /// pm.insert("192.168.1.0/24".parse()?, 1);
308    ///
309    /// assert_eq!(pm.entry("192.168.1.0/24".parse()?).or_default(), &1);
310    /// assert_eq!(pm.entry("192.168.2.0/24".parse()?).or_default(), &0);
311    ///
312    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), Some(&1));
313    /// assert_eq!(pm.get(&"192.168.2.0/24".parse()?), Some(&0));
314    /// # Ok(())
315    /// # }
316    /// # #[cfg(not(feature = "ipnet"))]
317    /// # fn main() {}
318    /// ```
319    ///
320    /// This function will *not* replace the prefix in the map if it already exists.
321    ///
322    /// ```
323    /// # use prefix_trie::*;
324    /// # #[cfg(feature = "ipnet")]
325    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
326    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
327    /// pm.insert("192.168.1.1/24".parse()?, 1);
328    /// pm.entry("192.168.1.2/24".parse()?).or_default();
329    /// assert_eq!(
330    ///     pm.get_key_value(&"192.168.1.0/24".parse()?),
331    ///     Some((&"192.168.1.1/24".parse()?, &1)) // prefix is not overwritten.
332    /// );
333    /// # Ok(())
334    /// # }
335    /// # #[cfg(not(feature = "ipnet"))]
336    /// # fn main() {}
337    /// ```
338    #[allow(clippy::unwrap_or_default)]
339    #[inline(always)]
340    pub fn or_default(self) -> &'a mut T {
341        self.or_insert_with(Default::default)
342    }
343}
344
345impl<'a, P, T> VacantEntry<'a, P, T>
346where
347    P: Prefix,
348{
349    fn _insert(self, v: T) -> &'a mut Node<P, T> {
350        match self.direction {
351            DirectionForInsert::Reached => {
352                // increment the count, as node.value will be `None`. We do it here as we borrow
353                // `map` mutably in the next line.
354                self.map.count += 1;
355                let node = &mut self.map.table[self.idx];
356                node.prefix = self.prefix;
357                debug_assert!(node.value.is_none());
358                node.value = Some(v);
359                node
360            }
361            DirectionForInsert::NewLeaf { right } => {
362                let new = self.map.new_node(self.prefix, Some(v));
363                self.map.table.set_child(self.idx, new, right);
364                &mut self.map.table[new]
365            }
366            DirectionForInsert::NewChild { right, child_right } => {
367                let new = self.map.new_node(self.prefix, Some(v));
368                let child = self.map.table.set_child(self.idx, new, right).unwrap();
369                self.map.table.set_child(new, child, child_right);
370                &mut self.map.table[new]
371            }
372            DirectionForInsert::NewBranch {
373                branch_prefix,
374                right,
375                prefix_right,
376            } => {
377                let branch = self.map.new_node(branch_prefix, None);
378                let new = self.map.new_node(self.prefix, Some(v));
379                let child = self.map.table.set_child(self.idx, branch, right).unwrap();
380                self.map.table.set_child(branch, new, prefix_right);
381                self.map.table.set_child(branch, child, !prefix_right);
382                &mut self.map.table[new]
383            }
384            DirectionForInsert::Enter { .. } => unreachable!(),
385        }
386    }
387}
388
389impl<P, T> OccupiedEntry<'_, P, T> {
390    /// Gets a reference to the key in the entry. This is the key that is currently stored, and not
391    /// the key that was used in the insert.
392    ///
393    /// ```
394    /// # use prefix_trie::*;
395    /// use prefix_trie::map::Entry;
396    /// # #[cfg(feature = "ipnet")]
397    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
398    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
399    /// pm.insert("192.168.1.0/24".parse()?, 1);
400    /// match pm.entry("192.168.1.1/24".parse()?) {
401    ///     Entry::Occupied(e) => assert_eq!(e.key(), &"192.168.1.0/24".parse()?),
402    ///     Entry::Vacant(_) => unreachable!(),
403    /// }
404    /// # Ok(())
405    /// # }
406    /// # #[cfg(not(feature = "ipnet"))]
407    /// # fn main() {}
408    /// ```
409    pub fn key(&self) -> &P {
410        &self.node.prefix
411    }
412
413    /// Gets a reference to the value in the entry.
414    ///
415    /// ```
416    /// # use prefix_trie::*;
417    /// use prefix_trie::map::Entry;
418    /// # #[cfg(feature = "ipnet")]
419    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
420    ///
421    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
422    /// pm.insert("192.168.1.0/24".parse()?, 1);
423    /// match pm.entry("192.168.1.0/24".parse()?) {
424    ///     Entry::Occupied(e) => assert_eq!(e.get(), &1),
425    ///     Entry::Vacant(_) => unreachable!(),
426    /// }
427    /// # Ok(())
428    /// # }
429    /// # #[cfg(not(feature = "ipnet"))]
430    /// # fn main() {}
431    /// ```
432    pub fn get(&self) -> &T {
433        self.node.value.as_ref().unwrap()
434    }
435
436    /// Gets a mutable reference to the value in the entry.
437    ///
438    /// This call will not modify the prefix stored in the tree. In case the prefix used to create
439    /// the entry is different from the stored one (has additional information in the host part),
440    /// and you wish that prefix to be overwritten, use `insert`.
441    ///
442    /// ```
443    /// # use prefix_trie::*;
444    /// use prefix_trie::map::Entry;
445    /// # #[cfg(feature = "ipnet")]
446    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
447    ///
448    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
449    /// pm.insert("192.168.1.0/24".parse()?, 1);
450    /// match pm.entry("192.168.1.0/24".parse()?) {
451    ///     Entry::Occupied(mut e) => *e.get_mut() += 1,
452    ///     Entry::Vacant(_) => unreachable!(),
453    /// }
454    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), Some(&2));
455    /// # Ok(())
456    /// # }
457    /// # #[cfg(not(feature = "ipnet"))]
458    /// # fn main() {}
459    /// ```
460    pub fn get_mut(&mut self) -> &mut T {
461        self.node.value.as_mut().unwrap()
462    }
463
464    /// Insert a new value into the entry, returning the old value. This operation will also replace
465    /// the prefix with the provided one.
466    ///
467    /// ```
468    /// # use prefix_trie::*;
469    /// use prefix_trie::map::Entry;
470    /// # #[cfg(feature = "ipnet")]
471    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
472    ///
473    /// let mut pm: PrefixMap<ipnet::Ipv4Net, _> = PrefixMap::new();
474    /// pm.insert("192.168.1.0/24".parse()?, 1);
475    /// match pm.entry("192.168.1.0/24".parse()?) {
476    ///     Entry::Occupied(mut e) => assert_eq!(e.insert(10), 1),
477    ///     Entry::Vacant(_) => unreachable!(),
478    /// }
479    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), Some(&10));
480    /// # Ok(())
481    /// # }
482    /// # #[cfg(not(feature = "ipnet"))]
483    /// # fn main() {}
484    /// ```
485    pub fn insert(self, value: T) -> T {
486        self.node.prefix = self.prefix;
487        self.node.value.replace(value).unwrap()
488    }
489
490    /// Remove the current value and return it. The tree will not be modified (the same effect as
491    /// `PrefixMap::remove_keep_tree`).
492    ///
493    /// ```
494    /// # use prefix_trie::*;
495    /// use prefix_trie::map::Entry;
496    /// # #[cfg(feature = "ipnet")]
497    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
498    ///
499    /// let mut pm: PrefixMap<ipnet::Ipv4Net, i32> = PrefixMap::new();
500    /// pm.insert("192.168.1.0/24".parse()?, 1);
501    /// match pm.entry("192.168.1.0/24".parse()?) {
502    ///     Entry::Occupied(mut e) => assert_eq!(e.remove(), 1),
503    ///     Entry::Vacant(_) => unreachable!(),
504    /// }
505    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), None);
506    /// # Ok(())
507    /// # }
508    /// # #[cfg(not(feature = "ipnet"))]
509    /// # fn main() {}
510    /// ```
511    pub fn remove(&mut self) -> T {
512        self.node.value.take().unwrap()
513    }
514}
515
516impl<P, T> VacantEntry<'_, P, T> {
517    /// Gets a reference to the key in the entry.
518    ///
519    /// ```
520    /// # use prefix_trie::*;
521    /// use prefix_trie::map::Entry;
522    /// # #[cfg(feature = "ipnet")]
523    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
524    /// let mut pm: PrefixMap<ipnet::Ipv4Net, i32> = PrefixMap::new();
525    /// match pm.entry("192.168.1.0/24".parse()?) {
526    ///     Entry::Vacant(e) => assert_eq!(e.key(), &"192.168.1.0/24".parse()?),
527    ///     Entry::Occupied(_) => unreachable!(),
528    /// }
529    /// # Ok(())
530    /// # }
531    /// # #[cfg(not(feature = "ipnet"))]
532    /// # fn main() {}
533    /// ```
534    pub fn key(&self) -> &P {
535        &self.prefix
536    }
537}
538
539impl<'a, P, T> VacantEntry<'a, P, T>
540where
541    P: Prefix,
542{
543    /// Get a mutable reference to the value. If the value is yet empty, set it to the given default
544    /// value.
545    ///
546    /// ```
547    /// # use prefix_trie::*;
548    /// use prefix_trie::map::Entry;
549    /// # #[cfg(feature = "ipnet")]
550    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
551    /// let mut pm: PrefixMap<ipnet::Ipv4Net, i32> = PrefixMap::new();
552    /// match pm.entry("192.168.1.0/24".parse()?) {
553    ///     Entry::Vacant(mut e) => assert_eq!(e.insert(10), &10),
554    ///     Entry::Occupied(_) => unreachable!(),
555    /// }
556    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), Some(&10));
557    /// # Ok(())
558    /// # }
559    /// # #[cfg(not(feature = "ipnet"))]
560    /// # fn main() {}
561    /// ```
562    pub fn insert(self, default: T) -> &'a mut T {
563        let node = self._insert(default);
564        node.value.as_mut().unwrap()
565    }
566
567    /// Get a mutable reference to the value. If the value is yet empty, set it to the return value
568    /// from the given function.
569    ///
570    /// ```
571    /// # use prefix_trie::*;
572    /// use prefix_trie::map::Entry;
573    /// # #[cfg(feature = "ipnet")]
574    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
575    /// let mut pm: PrefixMap<ipnet::Ipv4Net, i32> = PrefixMap::new();
576    /// match pm.entry("192.168.1.0/24".parse()?) {
577    ///     Entry::Vacant(mut e) => assert_eq!(e.insert_with(|| 10), &10),
578    ///     Entry::Occupied(_) => unreachable!(),
579    /// }
580    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), Some(&10));
581    /// # Ok(())
582    /// # }
583    /// # #[cfg(not(feature = "ipnet"))]
584    /// # fn main() {}
585    /// ```
586    pub fn insert_with<F: FnOnce() -> T>(self, default: F) -> &'a mut T {
587        let node = self._insert(default());
588        node.value.as_mut().unwrap()
589    }
590}
591
592impl<'a, P, T> VacantEntry<'a, P, T>
593where
594    P: Prefix,
595    T: Default,
596{
597    /// Get a mutable reference to the value. If the value is yet empty, set it to the default value
598    /// using `Default::default()`.
599    ///
600    /// ```
601    /// # use prefix_trie::*;
602    /// use prefix_trie::map::Entry;
603    /// # #[cfg(feature = "ipnet")]
604    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
605    /// let mut pm: PrefixMap<ipnet::Ipv4Net, i32> = PrefixMap::new();
606    /// match pm.entry("192.168.1.0/24".parse()?) {
607    ///     Entry::Vacant(e) => assert_eq!(e.default(), &0),
608    ///     Entry::Occupied(_) => unreachable!(),
609    /// }
610    /// assert_eq!(pm.get(&"192.168.1.0/24".parse()?), Some(&0));
611    /// # Ok(())
612    /// # }
613    /// # #[cfg(not(feature = "ipnet"))]
614    /// # fn main() {}
615    /// ```
616    pub fn default(self) -> &'a mut T {
617        let node = self._insert(Default::default());
618        node.value.as_mut().unwrap()
619    }
620}