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