Skip to main content

prefix_trie/map/
entry.rs

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