prefix_trie/trieview/
mod.rs

1//! A [`TrieView`] (or a [`TrieViewMut`]) is a pointer to a specific element in a PrefixTrie, representing the sub-tree
2//! rooted at that node.
3//!
4//! This module allows you to perform Set operations (union, intersection, difference) on
5//! [`PrefixMap`]s and [`PrefixSet`]s, optionally of only a trie-view.
6
7use crate::{
8    inner::{Direction, DirectionForInsert, Node, Table},
9    map::{Iter, IterMut, Keys, Values, ValuesMut},
10    to_right, Prefix, PrefixMap, PrefixSet,
11};
12
13/// A trait for creating a [`TrieView`] of `self`.
14pub trait AsView<'a, P: Prefix, T>: Sized {
15    /// Get a TrieView rooted at the origin (referencing the entire trie).
16    fn view(self) -> TrieView<'a, P, T>;
17
18    /// Get a TrieView rooted at the given `prefix`. If that `prefix` is not part of the trie, `None`
19    /// is returned. Calling this function is identical to `self.view().find(prefix)`.
20    fn view_at(self, prefix: P) -> Option<TrieView<'a, P, T>> {
21        self.view().find(prefix)
22    }
23}
24
25impl<'a, P: Prefix, T> AsView<'a, P, T> for TrieView<'a, P, T> {
26    fn view(self) -> TrieView<'a, P, T> {
27        self
28    }
29}
30
31impl<'b: 'a, 'a, P: Prefix + Clone, T> AsView<'a, P, T> for &'a TrieViewMut<'b, P, T> {
32    fn view(self) -> TrieView<'a, P, T> {
33        TrieView {
34            table: self.table,
35            loc: self.loc.clone(),
36        }
37    }
38}
39
40impl<'a, P: Prefix, T> AsView<'a, P, T> for &'a PrefixMap<P, T> {
41    fn view(self) -> TrieView<'a, P, T> {
42        TrieView {
43            table: &self.table,
44            loc: ViewLoc::Node(0),
45        }
46    }
47}
48
49impl<'a, P: Prefix> AsView<'a, P, ()> for &'a PrefixSet<P> {
50    fn view(self) -> TrieView<'a, P, ()> {
51        TrieView {
52            table: &self.0.table,
53            loc: ViewLoc::Node(0),
54        }
55    }
56}
57
58/// A subtree of a prefix-trie rooted at a specific node.
59///
60/// The view can point to one of three possible things:
61/// - A node in the tree that is actually present in the map,
62/// - A branching node that does not exist in the map, but is needed for the tree structure (or that
63///   was deleted using the function `remove_keep_tree`)
64/// - A virtual node that does not exist as a node in the tree. This is only the case if you call
65///   [`TrieView::find`] or [`AsView::view_at`] with a node that is not present in the tree, but
66///   that contains elements present in the tree. Virtual nodes are treated as if they are actually
67///   present in the tree as branching nodes.
68pub struct TrieView<'a, P, T> {
69    table: &'a Table<P, T>,
70    loc: ViewLoc<P>,
71}
72
73#[derive(Clone, Copy)]
74enum ViewLoc<P> {
75    Node(usize),
76    Virtual(P, usize),
77}
78
79impl<P> ViewLoc<P> {
80    fn idx(&self) -> usize {
81        match self {
82            ViewLoc::Node(i) | ViewLoc::Virtual(_, i) => *i,
83        }
84    }
85}
86
87impl<P: Copy, T> Copy for TrieView<'_, P, T> {}
88
89impl<P: Clone, T> Clone for TrieView<'_, P, T> {
90    fn clone(&self) -> Self {
91        Self {
92            table: self.table,
93            loc: self.loc.clone(),
94        }
95    }
96}
97
98impl<P: std::fmt::Debug, T: std::fmt::Debug> std::fmt::Debug for TrieView<'_, P, T> {
99    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100        f.debug_tuple("View").field(self.prefix()).finish()
101    }
102}
103
104impl<'a, P, T> TrieView<'a, P, T>
105where
106    P: Prefix,
107{
108    /// Find `prefix`, returning a new view that points to the first node that is contained
109    /// within that prefix (or `prefix` itself). Only the current view is searched. If `prefix`
110    /// is not present in the current view referenced by `self` (including any sub-prefix of
111    /// `prefix`), the function returns `None`.
112    ///
113    /// ```
114    /// # use prefix_trie::*;
115    /// # #[cfg(feature = "ipnet")]
116    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
117    ///
118    /// # #[cfg(feature = "ipnet")]
119    /// # {
120    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
121    ///     (net!("192.168.0.0/20"), 1),
122    ///     (net!("192.168.0.0/22"), 2),
123    ///     (net!("192.168.0.0/24"), 3),
124    ///     (net!("192.168.2.0/23"), 4),
125    ///     (net!("192.168.4.0/22"), 5),
126    /// ]);
127    /// let sub = map.view();
128    /// assert_eq!(
129    ///     sub.find(net!("192.168.0.0/21")).unwrap().keys().collect::<Vec<_>>(),
130    ///     vec![
131    ///         &net!("192.168.0.0/22"),
132    ///         &net!("192.168.0.0/24"),
133    ///         &net!("192.168.2.0/23"),
134    ///         &net!("192.168.4.0/22"),
135    ///     ]
136    /// );
137    /// assert_eq!(
138    ///     sub.find(net!("192.168.0.0/22")).unwrap().keys().collect::<Vec<_>>(),
139    ///     vec![
140    ///         &net!("192.168.0.0/22"),
141    ///         &net!("192.168.0.0/24"),
142    ///         &net!("192.168.2.0/23"),
143    ///     ]
144    /// );
145    /// # }
146    /// ```
147    pub fn find(&self, prefix: P) -> Option<TrieView<'a, P, T>> {
148        let mut idx = self.loc.idx();
149        loop {
150            match self.table.get_direction_for_insert(idx, &prefix) {
151                DirectionForInsert::Enter { next, .. } => {
152                    idx = next;
153                }
154                DirectionForInsert::Reached => {
155                    return Some(Self {
156                        table: self.table,
157                        loc: ViewLoc::Node(idx),
158                    })
159                }
160                DirectionForInsert::NewChild { right, .. } => {
161                    // view at a virtual node between idx and the right child of idx.
162                    return Some(Self {
163                        table: self.table,
164                        loc: ViewLoc::Virtual(prefix, self.table.get_child(idx, right).unwrap()),
165                    });
166                }
167                DirectionForInsert::NewLeaf { .. } | DirectionForInsert::NewBranch { .. } => {
168                    return None
169                }
170            }
171        }
172    }
173
174    /// Find `prefix`, returning a new view that points to that node. Only the current view is
175    /// searched. If this prefix is not present in the view pointed to by `self`, the function
176    /// returns `None`.
177    ///
178    /// ```
179    /// # use prefix_trie::*;
180    /// # #[cfg(feature = "ipnet")]
181    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
182    ///
183    /// # #[cfg(feature = "ipnet")]
184    /// # {
185    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
186    ///     (net!("192.168.0.0/20"), 1),
187    ///     (net!("192.168.0.0/22"), 2),
188    ///     (net!("192.168.0.0/24"), 3),
189    ///     (net!("192.168.2.0/23"), 4),
190    ///     (net!("192.168.4.0/22"), 5),
191    /// ]);
192    /// let sub = map.view();
193    /// assert!(sub.find_exact(&net!("192.168.0.0/21")).is_none());
194    /// assert_eq!(
195    ///     sub.find_exact(&net!("192.168.0.0/22")).unwrap().keys().collect::<Vec<_>>(),
196    ///     vec![
197    ///         &net!("192.168.0.0/22"),
198    ///         &net!("192.168.0.0/24"),
199    ///         &net!("192.168.2.0/23"),
200    ///     ]
201    /// );
202    /// # }
203    /// ```
204    pub fn find_exact(&self, prefix: &P) -> Option<TrieView<'a, P, T>> {
205        let mut idx = self.loc.idx();
206        loop {
207            match self.table.get_direction(idx, prefix) {
208                Direction::Reached => {
209                    return self.table[idx].value.is_some().then_some(Self {
210                        table: self.table,
211                        loc: ViewLoc::Node(idx),
212                    })
213                }
214                Direction::Enter { next, .. } => idx = next,
215                Direction::Missing => return None,
216            }
217        }
218    }
219
220    /// Find the longest match of `prefix`, returning a new view that points to that node. Only
221    /// the given view is searched. If the prefix is not present in the view pointed to by
222    /// `self`, the function returns `None`.
223    ///
224    /// Only views to nodes that are present in the map are returned, not to branching nodes.
225    ///
226    /// ```
227    /// # use prefix_trie::*;
228    /// # #[cfg(feature = "ipnet")]
229    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
230    ///
231    /// # #[cfg(feature = "ipnet")]
232    /// # {
233    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
234    ///     (net!("192.168.0.0/20"), 1),
235    ///     (net!("192.168.0.0/22"), 2),
236    ///     (net!("192.168.0.0/24"), 3),
237    ///     (net!("192.168.2.0/23"), 4),
238    ///     (net!("192.168.4.0/22"), 5),
239    /// ]);
240    /// let sub = map.view();
241    /// assert_eq!(
242    ///     sub.find_lpm(&net!("192.168.0.0/21")).unwrap().keys().collect::<Vec<_>>(),
243    ///     vec![
244    ///         &net!("192.168.0.0/20"),
245    ///         &net!("192.168.0.0/22"),
246    ///         &net!("192.168.0.0/24"),
247    ///         &net!("192.168.2.0/23"),
248    ///         &net!("192.168.4.0/22"),
249    ///     ]
250    /// );
251    /// assert_eq!(
252    ///     sub.find_lpm(&net!("192.168.0.0/22")).unwrap().keys().collect::<Vec<_>>(),
253    ///     vec![
254    ///         &net!("192.168.0.0/22"),
255    ///         &net!("192.168.0.0/24"),
256    ///         &net!("192.168.2.0/23"),
257    ///     ]
258    /// );
259    /// # }
260    /// ```
261    pub fn find_lpm(&self, prefix: &P) -> Option<TrieView<'a, P, T>> {
262        let mut idx = self.loc.idx();
263        let mut best_match = None;
264        loop {
265            if self.table[idx].value.is_some() {
266                best_match = Some(idx);
267            }
268            match self.table.get_direction(idx, prefix) {
269                Direction::Enter { next, .. } => idx = next,
270                _ => {
271                    return best_match.map(|idx| Self {
272                        table: self.table,
273                        loc: ViewLoc::Node(idx),
274                    })
275                }
276            }
277        }
278    }
279
280    /// Get the left branch at the current view. The right branch contains all prefix that are
281    /// contained within `self.prefix()`, and for which the next bit is set to 0.
282    ///
283    /// ```
284    /// # use prefix_trie::*;
285    /// # #[cfg(feature = "ipnet")]
286    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
287    ///
288    /// # #[cfg(feature = "ipnet")]
289    /// # {
290    /// let map: PrefixSet<ipnet::Ipv4Net> = PrefixSet::from_iter([
291    ///     net!("1.0.0.0/8"),
292    ///     net!("1.0.0.0/16"),
293    ///     net!("1.0.128.0/17"),
294    ///     net!("1.1.0.0/16"),
295    /// ]);
296    ///
297    /// let view = map.view_at(net!("1.0.0.0/8")).unwrap();
298    /// assert_eq!(view.prefix(), &net!("1.0.0.0/8"));
299    ///
300    /// let view = view.left().unwrap();
301    /// assert_eq!(view.prefix(), &net!("1.0.0.0/15"));
302    ///
303    /// let view = view.left().unwrap();
304    /// assert_eq!(view.prefix(), &net!("1.0.0.0/16"));
305    ///
306    /// assert!(view.left().is_none());
307    /// # }
308    /// ```
309    pub fn left(&self) -> Option<Self> {
310        match &self.loc {
311            ViewLoc::Node(idx) => Some(Self {
312                table: self.table,
313                loc: ViewLoc::Node(self.table[*idx].left?),
314            }),
315            ViewLoc::Virtual(p, idx) => {
316                // first, check if the node is on the left of the virtual one.
317                if !to_right(p, &self.table[*idx].prefix) {
318                    Some(Self {
319                        table: self.table,
320                        loc: ViewLoc::Node(*idx),
321                    })
322                } else {
323                    None
324                }
325            }
326        }
327    }
328
329    /// Get the right branch at the current view. The right branch contains all prefix that are
330    /// contained within `self.prefix()`, and for which the next bit is set to 1.
331    ///
332    /// ```
333    /// # use prefix_trie::*;
334    /// # #[cfg(feature = "ipnet")]
335    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
336    ///
337    /// # #[cfg(feature = "ipnet")]
338    /// # {
339    /// let map: PrefixSet<ipnet::Ipv4Net> = PrefixSet::from_iter([
340    ///     net!("1.0.0.0/8"),
341    ///     net!("1.0.0.0/16"),
342    ///     net!("1.1.0.0/16"),
343    ///     net!("1.1.0.0/24"),
344    /// ]);
345    ///
346    /// let view = map.view_at(net!("1.0.0.0/8")).unwrap();
347    /// assert_eq!(view.prefix(), &net!("1.0.0.0/8"));
348    ///
349    /// assert!(view.right().is_none());
350    /// let view = view.left().unwrap();
351    /// assert_eq!(view.prefix(), &net!("1.0.0.0/15"));
352    ///
353    /// let view = view.right().unwrap();
354    /// assert_eq!(view.prefix(), &net!("1.1.0.0/16"));
355    ///
356    /// assert!(view.right().is_none());
357    /// # }
358    /// ```
359    pub fn right(&self) -> Option<Self> {
360        match &self.loc {
361            ViewLoc::Node(idx) => Some(Self {
362                table: self.table,
363                loc: ViewLoc::Node(self.table[*idx].right?),
364            }),
365            ViewLoc::Virtual(p, idx) => {
366                // first, check if the node is on the right of the virtual one.
367                if to_right(p, &self.table[*idx].prefix) {
368                    Some(Self {
369                        table: self.table,
370                        loc: ViewLoc::Node(*idx),
371                    })
372                } else {
373                    None
374                }
375            }
376        }
377    }
378}
379
380impl<'a, P, T> TrieView<'a, P, T> {
381    /// Iterate over all elements in the given view (including the element itself), in
382    /// lexicographic order.
383    ///
384    /// ```
385    /// # use prefix_trie::*;
386    /// # #[cfg(feature = "ipnet")]
387    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
388    ///
389    /// # #[cfg(feature = "ipnet")]
390    /// # {
391    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
392    ///     (net!("192.168.0.0/20"), 1),
393    ///     (net!("192.168.0.0/22"), 2),
394    ///     (net!("192.168.0.0/24"), 3),
395    ///     (net!("192.168.2.0/23"), 4),
396    /// ]);
397    /// let sub = map.view_at(net!("192.168.0.0/22")).unwrap();
398    /// assert_eq!(
399    ///     sub.iter().collect::<Vec<_>>(),
400    ///     vec![
401    ///         (&net!("192.168.0.0/22"), &2),
402    ///         (&net!("192.168.0.0/24"), &3),
403    ///         (&net!("192.168.2.0/23"), &4),
404    ///     ]
405    /// );
406    /// # }
407    /// ```
408    pub fn iter(&self) -> Iter<'a, P, T> {
409        Iter::new(self.table, vec![self.loc.idx()])
410    }
411
412    /// Iterate over all keys in the given view (including the element itself), in lexicographic
413    /// order.
414    ///
415    /// ```
416    /// # use prefix_trie::*;
417    /// # #[cfg(feature = "ipnet")]
418    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
419    ///
420    /// # #[cfg(feature = "ipnet")]
421    /// # {
422    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
423    ///     (net!("192.168.0.0/20"), 1),
424    ///     (net!("192.168.0.0/22"), 2),
425    ///     (net!("192.168.0.0/24"), 3),
426    ///     (net!("192.168.2.0/23"), 4),
427    /// ]);
428    /// let sub = map.view_at(net!("192.168.0.0/22")).unwrap();
429    /// assert_eq!(
430    ///     sub.keys().collect::<Vec<_>>(),
431    ///     vec![&net!("192.168.0.0/22"), &net!("192.168.0.0/24"), &net!("192.168.2.0/23")]
432    /// );
433    /// # }
434    /// ```
435    pub fn keys(&self) -> Keys<'a, P, T> {
436        Keys { inner: self.iter() }
437    }
438
439    /// Iterate over all values in the given view (including the element itself), in lexicographic
440    /// order.
441    ///
442    /// ```
443    /// # use prefix_trie::*;
444    /// # #[cfg(feature = "ipnet")]
445    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
446    ///
447    /// # #[cfg(feature = "ipnet")]
448    /// # {
449    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
450    ///     (net!("192.168.0.0/20"), 1),
451    ///     (net!("192.168.0.0/22"), 2),
452    ///     (net!("192.168.0.0/24"), 3),
453    ///     (net!("192.168.2.0/23"), 4),
454    /// ]);
455    /// let sub = map.view_at(net!("192.168.0.0/22")).unwrap();
456    /// assert_eq!(sub.values().collect::<Vec<_>>(), vec![&2, &3, &4]);
457    /// # }
458    /// ```
459    pub fn values(&self) -> Values<'a, P, T> {
460        Values { inner: self.iter() }
461    }
462
463    /// Get a reference to the prefix that is currently pointed at. This prefix might not exist
464    /// explicitly in the map/set, but may be used as a branching node (or when you call
465    /// `remove_keep_tree`).
466    ///
467    /// ```
468    /// # use prefix_trie::*;
469    /// # #[cfg(feature = "ipnet")]
470    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
471    ///
472    /// # #[cfg(feature = "ipnet")]
473    /// # {
474    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
475    ///     (net!("192.168.0.0/20"), 1),
476    ///     (net!("192.168.0.0/22"), 2),
477    /// ]);
478    ///
479    /// assert_eq!(map.view_at(net!("192.168.0.0/20")).unwrap().prefix(), &net!("192.168.0.0/20"));
480    /// assert_eq!(map.view_at(net!("192.168.0.0/21")).unwrap().prefix(), &net!("192.168.0.0/21"));
481    /// assert_eq!(map.view_at(net!("192.168.0.0/22")).unwrap().prefix(), &net!("192.168.0.0/22"));
482    /// # }
483    /// ```
484    pub fn prefix(&self) -> &P {
485        match &self.loc {
486            ViewLoc::Node(idx) => &self.table[*idx].prefix,
487            ViewLoc::Virtual(p, _) => p,
488        }
489    }
490
491    /// Get a reference to the value at the root of the current view. This function may return
492    /// `None` if `self` is pointing at a branching node.
493    ///
494    /// ```
495    /// # use prefix_trie::*;
496    /// # #[cfg(feature = "ipnet")]
497    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
498    ///
499    /// # #[cfg(feature = "ipnet")]
500    /// # {
501    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
502    ///     (net!("192.168.0.0/20"), 1),
503    ///     (net!("192.168.0.0/22"), 2),
504    /// ]);
505    ///
506    /// assert_eq!(map.view_at(net!("192.168.0.0/20")).unwrap().value(), Some(&1));
507    /// assert_eq!(map.view_at(net!("192.168.0.0/21")).unwrap().value(), None);
508    /// assert_eq!(map.view_at(net!("192.168.0.0/22")).unwrap().value(), Some(&2));
509    /// # }
510    /// ```
511    pub fn value(&self) -> Option<&'a T> {
512        match &self.loc {
513            ViewLoc::Node(idx) => self.table[*idx].value.as_ref(),
514            ViewLoc::Virtual(_, _) => None,
515        }
516    }
517
518    /// Get a reference to both the prefix and the value. This function may return `None` if either
519    /// `self` is pointing at a branching node.
520    ///
521    /// ```
522    /// # use prefix_trie::*;
523    /// # #[cfg(feature = "ipnet")]
524    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
525    ///
526    /// # #[cfg(feature = "ipnet")]
527    /// # {
528    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
529    ///     (net!("192.168.0.0/20"), 1),
530    ///     (net!("192.168.0.0/22"), 2),
531    /// ]);
532    ///
533    /// assert_eq!(
534    ///     map.view_at(net!("192.168.0.0/20")).unwrap().prefix_value(),
535    ///     Some((&net!("192.168.0.0/20"), &1))
536    /// );
537    /// assert_eq!(map.view_at(net!("192.168.0.0/21")).unwrap().prefix_value(), None);
538    /// # }
539    /// ```
540    pub fn prefix_value(&self) -> Option<(&'a P, &'a T)> {
541        match &self.loc {
542            ViewLoc::Node(idx) => self.table[*idx].prefix_value(),
543            ViewLoc::Virtual(_, _) => None,
544        }
545    }
546}
547
548impl<'a, P, T> IntoIterator for TrieView<'a, P, T> {
549    type Item = (&'a P, &'a T);
550    type IntoIter = Iter<'a, P, T>;
551
552    fn into_iter(self) -> Self::IntoIter {
553        self.iter()
554    }
555}
556
557/// A trait for creating a [`TrieViewMut`] of `self`.
558pub trait AsViewMut<'a, P: Prefix, T>: Sized {
559    /// Get a mutable view rooted at the origin (referencing the entire trie).
560    fn view_mut(self) -> TrieViewMut<'a, P, T>;
561
562    /// Get a mutable view rooted at the given `prefix`. If that `prefix` is not part of the trie, `None`
563    /// is returned. Calling this function is identical to `self.view().find(prefix)`.
564    fn view_mut_at(self, prefix: P) -> Option<TrieViewMut<'a, P, T>> {
565        self.view_mut().find(prefix).ok()
566    }
567}
568
569impl<'a, P: Prefix, T> AsViewMut<'a, P, T> for TrieViewMut<'a, P, T> {
570    fn view_mut(self) -> TrieViewMut<'a, P, T> {
571        self
572    }
573}
574
575impl<'a, P: Prefix, T> AsViewMut<'a, P, T> for &'a mut PrefixMap<P, T> {
576    fn view_mut(self) -> TrieViewMut<'a, P, T> {
577        // Safety: We borrow the prefixmap mutably here. Thus, this is the only mutable reference,
578        // and we can create such a view to the root (referencing the entire tree mutably).
579        unsafe { TrieViewMut::new(&self.table, ViewLoc::Node(0)) }
580    }
581}
582
583impl<'a, P: Prefix> AsViewMut<'a, P, ()> for &'a mut PrefixSet<P> {
584    fn view_mut(self) -> TrieViewMut<'a, P, ()> {
585        self.0.view_mut()
586    }
587}
588
589/// A mutable view of a prefix-trie rooted at a specific node.
590///
591/// **Note**: You can get a `TrieView` from `TrieViewMut` by calling [`AsView::view`]. This will
592/// create a view that has an immutable reference to the mutable view. This allows you to temprarily
593/// borrow the subtrie immutably (to perform set operations). Once all references are dropped, you
594/// can still use the mutable reference.
595///
596/// ```
597/// # use prefix_trie::*;
598/// # #[cfg(feature = "ipnet")]
599/// # macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
600/// # #[cfg(feature = "ipnet")]
601/// # {
602/// # let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
603/// #     (net!("192.168.0.0/20"), 1),
604/// #     (net!("192.168.0.0/22"), 2),
605/// #     (net!("192.168.0.0/24"), 3),
606/// #     (net!("192.168.2.0/23"), 4),
607/// # ]);
608/// # let other: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
609/// #     (net!("192.168.0.0/22"), 10),
610/// #     (net!("192.168.0.0/23"), 20),
611/// #     (net!("192.168.2.0/24"), 30),
612/// # ]);
613/// let mut view: TrieViewMut<_, _> = // ...;
614/// # map.view_mut();
615/// // find the first element that is in the view and in another map.
616/// if let Some((p, _, _)) = view.view().union(&other).find_map(|u| u.both()) {
617///     // remove that element from the map.
618///     let p = p.clone();
619///     view.find(p).unwrap().remove();
620/// }
621/// # }
622/// ```
623///
624/// The view can point to one of three possible things:
625/// - A node in the tree that is actually present in the map,
626/// - A branching node that does not exist in the map, but is needed for the tree structure (or that
627///   was deleted using the function `remove_keep_tree`)
628/// - A virtual node that does not exist as a node in the tree. This is only the case if you call
629///   [`TrieViewMut::find`] or [`AsViewMut::view_mut_at`] with a node that is not present in the
630///   tree, but that contains elements present in the tree. Virtual nodes are treated as if they are
631///   actually present in the tree as branching.
632pub struct TrieViewMut<'a, P, T> {
633    table: &'a Table<P, T>,
634    loc: ViewLoc<P>,
635}
636
637impl<'a, P, T> TrieViewMut<'a, P, T> {
638    /// # Safety
639    /// - First, ensure that `'a` is tied to a mutable reference `&'a Table<P, T>`.
640    /// - Second, you must guarantee that, if multiple `TrieViewMut` exist, all of them point to
641    ///   nodes that are located on separate sub-trees. You must guarantee that no `TrieViewMut` is
642    ///   contained within another `TrieViewMut` or `TrieView`. Also, you must guarantee that no
643    ///   `TrieView` is contained within a `TrieViewMut`.
644    unsafe fn new(table: &'a Table<P, T>, loc: ViewLoc<P>) -> Self {
645        Self { table, loc }
646    }
647}
648
649impl<P: std::fmt::Debug, T: std::fmt::Debug> std::fmt::Debug for TrieViewMut<'_, P, T> {
650    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
651        f.debug_tuple("ViewMut").field(self.prefix()).finish()
652    }
653}
654
655impl<P, T> TrieViewMut<'_, P, T>
656where
657    P: Prefix,
658{
659    /// Find `prefix`, returning a new view that points to the first node that is contained
660    /// within that prefix (or `prefix` itself). Only the current view is searched. If `prefix`
661    /// is not present in the current view referenced by `self` (including any sub-prefix of
662    /// `prefix`), the function returns the previous view as `Err(self)`.
663    ///
664    /// ```
665    /// # use prefix_trie::*;
666    /// # #[cfg(feature = "ipnet")]
667    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
668    ///
669    /// # #[cfg(feature = "ipnet")]
670    /// # {
671    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
672    ///     (net!("192.168.0.0/20"), 1),
673    ///     (net!("192.168.0.0/22"), 2),
674    ///     (net!("192.168.0.0/24"), 3),
675    ///     (net!("192.168.2.0/23"), 4),
676    ///     (net!("192.168.4.0/22"), 5),
677    /// ]);
678    /// map.view_mut().find(net!("192.168.0.0/21")).unwrap().values_mut().for_each(|x| *x += 10);
679    /// assert_eq!(
680    ///     map.into_iter().collect::<Vec<_>>(),
681    ///     vec![
682    ///         (net!("192.168.0.0/20"), 1),
683    ///         (net!("192.168.0.0/22"), 12),
684    ///         (net!("192.168.0.0/24"), 13),
685    ///         (net!("192.168.2.0/23"), 14),
686    ///         (net!("192.168.4.0/22"), 15),
687    ///     ]
688    /// );
689    /// # }
690    /// ```
691    pub fn find(self, prefix: P) -> Result<Self, Self> {
692        // Safety: We own the entire sub-tree, including `idx` (which was reached from
693        // `self.idx`). Here, we return a new TrieViewMut pointing to that node (which
694        // is still not covered by any other view), while dropping `self`.
695
696        let mut idx = self.loc.idx();
697        loop {
698            match self.table.get_direction_for_insert(idx, &prefix) {
699                DirectionForInsert::Enter { next, .. } => {
700                    idx = next;
701                }
702                DirectionForInsert::Reached => {
703                    let new_loc = ViewLoc::Node(idx);
704                    return unsafe { Ok(Self::new(self.table, new_loc)) };
705                }
706                DirectionForInsert::NewChild { right, .. } => {
707                    // view at a virtual node between idx and the right child of idx.
708                    let new_loc =
709                        ViewLoc::Virtual(prefix, self.table.get_child(idx, right).unwrap());
710                    return unsafe { Ok(Self::new(self.table, new_loc)) };
711                }
712                DirectionForInsert::NewLeaf { .. } | DirectionForInsert::NewBranch { .. } => {
713                    return Err(self)
714                }
715            }
716        }
717    }
718
719    /// Find `prefix`, returning a new view that points to that node. Only the current view is
720    /// searched. If this prefix is not present in the view pointed to by `self`, the function
721    /// returns the previous view as `Err(self)`.
722    ///
723    /// ```
724    /// # use prefix_trie::*;
725    /// # #[cfg(feature = "ipnet")]
726    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
727    ///
728    /// # #[cfg(feature = "ipnet")]
729    /// # {
730    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
731    ///     (net!("192.168.0.0/20"), 1),
732    ///     (net!("192.168.0.0/22"), 2),
733    ///     (net!("192.168.0.0/24"), 3),
734    ///     (net!("192.168.2.0/23"), 4),
735    ///     (net!("192.168.4.0/22"), 5),
736    /// ]);
737    /// assert!(map.view_mut().find_exact(&net!("192.168.0.0/21")).is_err());
738    /// map.view_mut().find_exact(&net!("192.168.0.0/22")).unwrap().values_mut().for_each(|x| *x += 10);
739    /// assert_eq!(
740    ///     map.into_iter().collect::<Vec<_>>(),
741    ///     vec![
742    ///         (net!("192.168.0.0/20"), 1),
743    ///         (net!("192.168.0.0/22"), 12),
744    ///         (net!("192.168.0.0/24"), 13),
745    ///         (net!("192.168.2.0/23"), 14),
746    ///         (net!("192.168.4.0/22"), 5),
747    ///     ]
748    /// );
749    /// # }
750    /// ```
751    pub fn find_exact(self, prefix: &P) -> Result<Self, Self> {
752        let mut idx = self.loc.idx();
753        loop {
754            match self.table.get_direction(idx, prefix) {
755                Direction::Reached => {
756                    return if self.table[idx].value.is_some() {
757                        // Safety: We own the entire sub-tree, including `idx` (which was reached
758                        // from `self.idx`). Here, we return a new TrieViewMut pointing to that node
759                        // (which is still not covered by any other view), while dropping `self`.
760                        unsafe { Ok(Self::new(self.table, ViewLoc::Node(idx))) }
761                    } else {
762                        Err(self)
763                    };
764                }
765                Direction::Enter { next, .. } => idx = next,
766                Direction::Missing => return Err(self),
767            }
768        }
769    }
770
771    /// Find the longest match of `prefix`, returning a new view that points to that node. Only
772    /// the given view is searched. If the prefix is not present in the view pointed to by
773    /// `self`, the function returns the previous view as `Err(self)`.
774    ///
775    /// Only views to nodes that are present in the map are returned, not to branching nodes.
776    ///
777    /// ```
778    /// # use prefix_trie::*;
779    /// # #[cfg(feature = "ipnet")]
780    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
781    ///
782    /// # #[cfg(feature = "ipnet")]
783    /// # {
784    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
785    ///     (net!("192.168.0.0/20"), 1),
786    ///     (net!("192.168.0.0/22"), 2),
787    ///     (net!("192.168.0.0/24"), 3),
788    ///     (net!("192.168.2.0/23"), 4),
789    ///     (net!("192.168.4.0/22"), 5),
790    /// ]);
791    /// map.view_mut().find_lpm(&net!("192.168.0.0/22")).unwrap().values_mut().for_each(|x| *x += 10);
792    /// map.view_mut().find_lpm(&net!("192.168.0.0/23")).unwrap().values_mut().for_each(|x| *x += 100);
793    /// assert_eq!(
794    ///     map.into_iter().collect::<Vec<_>>(),
795    ///     vec![
796    ///         (net!("192.168.0.0/20"), 1),
797    ///         (net!("192.168.0.0/22"), 112),
798    ///         (net!("192.168.0.0/24"), 113),
799    ///         (net!("192.168.2.0/23"), 114),
800    ///         (net!("192.168.4.0/22"), 5),
801    ///     ]
802    /// );
803    /// # }
804    /// ```
805    pub fn find_lpm(self, prefix: &P) -> Result<Self, Self> {
806        let mut idx = self.loc.idx();
807        let mut best_match = None;
808        loop {
809            if self.table[idx].value.is_some() {
810                best_match = Some(idx);
811            }
812            match self.table.get_direction(idx, prefix) {
813                Direction::Enter { next, .. } => idx = next,
814                _ => {
815                    return if let Some(idx) = best_match {
816                        // Safety: We own the entire sub-tree, including `idx` (which was reached
817                        // from `self.idx`). Here, we return a new TrieViewMut pointing to that node
818                        // (which is still not covered by any other view), while dropping `self`.
819                        unsafe { Ok(Self::new(self.table, ViewLoc::Node(idx))) }
820                    } else {
821                        Err(self)
822                    };
823                }
824            }
825        }
826    }
827
828    /// Get the left branch at the current view. The right branch contains all prefix that are
829    /// contained within `self.prefix()`, and for which the next bit is set to 0. If the node has no
830    /// children to the left, the function will return the previous view as `Err(self)`.
831    ///
832    /// ```
833    /// # use prefix_trie::*;
834    /// # #[cfg(feature = "ipnet")]
835    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
836    ///
837    /// # #[cfg(feature = "ipnet")]
838    /// # {
839    /// let mut map: PrefixSet<ipnet::Ipv4Net> = PrefixSet::from_iter([
840    ///     net!("1.0.0.0/8"),
841    ///     net!("1.0.0.0/16"),
842    ///     net!("1.0.128.0/17"),
843    ///     net!("1.1.0.0/16"),
844    /// ]);
845    ///
846    /// let view = map.view_mut_at(net!("1.0.0.0/8")).unwrap();
847    /// assert_eq!(view.prefix(), &net!("1.0.0.0/8"));
848    ///
849    /// let view = view.left().unwrap();
850    /// assert_eq!(view.prefix(), &net!("1.0.0.0/15"));
851    ///
852    /// let view = view.left().unwrap();
853    /// assert_eq!(view.prefix(), &net!("1.0.0.0/16"));
854    ///
855    /// assert!(view.left().is_err());
856    /// # }
857    /// ```
858    pub fn left(self) -> Result<Self, Self> {
859        // Safety: We assume `self` was created while satisfying the safety conditions from
860        // `TrieViewMut::new`. Thus, `self` is the only TrieView referencing that root. Here, we
861        // construct a new `TrieViewMut` of the left child while destroying `self`, and thus,
862        // the safety conditions remain satisfied.
863
864        let left_idx = match &self.loc {
865            ViewLoc::Node(idx) => self.table[*idx].left,
866            ViewLoc::Virtual(p, idx) => {
867                // first, check if the node is on the left of the virtual one.
868                if !to_right(p, &self.table[*idx].prefix) {
869                    Some(*idx)
870                } else {
871                    None
872                }
873            }
874        };
875
876        if let Some(idx) = left_idx {
877            unsafe { Ok(Self::new(self.table, ViewLoc::Node(idx))) }
878        } else {
879            Err(self)
880        }
881    }
882
883    /// Get the right branch at the current view. The right branch contains all prefix that are
884    /// contained within `self.prefix()`, and for which the next bit is set to 1. If the node has no
885    /// children to the right, the function will return the previous view as `Err(self)`.
886    ///
887    /// ```
888    /// # use prefix_trie::*;
889    /// # #[cfg(feature = "ipnet")]
890    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
891    ///
892    /// # #[cfg(feature = "ipnet")]
893    /// # {
894    /// let mut map: PrefixSet<ipnet::Ipv4Net> = PrefixSet::from_iter([
895    ///     net!("1.0.0.0/8"),
896    ///     net!("1.0.0.0/16"),
897    ///     net!("1.1.0.0/16"),
898    ///     net!("1.1.0.0/24"),
899    /// ]);
900    ///
901    /// let view = map.view_mut_at(net!("1.0.0.0/8")).unwrap();
902    /// assert_eq!(view.prefix(), &net!("1.0.0.0/8"));
903    ///
904    /// let view = view.right().unwrap_err(); // there is no view on the right.
905    /// assert_eq!(view.prefix(), &net!("1.0.0.0/8"));
906    ///
907    /// let view = view.left().unwrap();
908    /// assert_eq!(view.prefix(), &net!("1.0.0.0/15"));
909    ///
910    /// let view = view.right().unwrap();
911    /// assert_eq!(view.prefix(), &net!("1.1.0.0/16"));
912    ///
913    /// assert!(view.right().is_err());
914    /// # }
915    /// ```
916    pub fn right(self) -> Result<Self, Self> {
917        // Safety: We assume `self` was created while satisfying the safety conditions from
918        // `TrieViewMut::new`. Thus, `self` is the only TrieView referencing that root. Here, we
919        // construct a new `TrieViewMut` of the right child while destroying `self`, and thus,
920        // the safety conditions remain satisfied.
921
922        let right_idx = match &self.loc {
923            ViewLoc::Node(idx) => self.table[*idx].right,
924            ViewLoc::Virtual(p, idx) => {
925                // first, check if the node is on the right of the virtual one.
926                if to_right(p, &self.table[*idx].prefix) {
927                    Some(*idx)
928                } else {
929                    None
930                }
931            }
932        };
933
934        if let Some(idx) = right_idx {
935            unsafe { Ok(Self::new(self.table, ViewLoc::Node(idx))) }
936        } else {
937            Err(self)
938        }
939    }
940
941    /// Returns `True` whether `self` has children to the left.
942    ///
943    /// ```
944    /// # use prefix_trie::*;
945    /// # #[cfg(feature = "ipnet")]
946    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
947    ///
948    /// # #[cfg(feature = "ipnet")]
949    /// # {
950    /// let mut map: PrefixSet<ipnet::Ipv4Net> = PrefixSet::from_iter([
951    ///     net!("1.0.0.0/8"),
952    ///     net!("1.0.0.0/9"),
953    /// ]);
954    ///
955    /// assert!(map.view_mut_at(net!("1.0.0.0/8")).unwrap().has_left());
956    /// assert!(!map.view_mut_at(net!("1.0.0.0/9")).unwrap().has_left());
957    /// # }
958    /// ```
959    pub fn has_left(&self) -> bool {
960        match &self.loc {
961            ViewLoc::Node(idx) => self.table[*idx].left.is_some(),
962            ViewLoc::Virtual(p, idx) => {
963                // first, check if the node is on the right of the virtual one.
964                !to_right(p, &self.table[*idx].prefix)
965            }
966        }
967    }
968
969    /// Returns `True` whether `self` has children to the right.
970    ///
971    /// ```
972    /// # use prefix_trie::*;
973    /// # #[cfg(feature = "ipnet")]
974    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
975    ///
976    /// # #[cfg(feature = "ipnet")]
977    /// # {
978    /// let mut map: PrefixSet<ipnet::Ipv4Net> = PrefixSet::from_iter([
979    ///     net!("1.0.0.0/8"),
980    ///     net!("1.128.0.0/9"),
981    /// ]);
982    ///
983    /// assert!(map.view_mut_at(net!("1.0.0.0/8")).unwrap().has_right());
984    /// assert!(!map.view_mut_at(net!("1.128.0.0/9")).unwrap().has_right());
985    /// # }
986    /// ```
987    pub fn has_right(&self) -> bool {
988        match &self.loc {
989            ViewLoc::Node(idx) => self.table[*idx].right.is_some(),
990            ViewLoc::Virtual(p, idx) => {
991                // first, check if the node is on the right of the virtual one.
992                to_right(p, &self.table[*idx].prefix)
993            }
994        }
995    }
996
997    /// Split `self` into two views, one pointing to the left and one pointing to the right child.
998    ///
999    /// ```
1000    /// # use prefix_trie::*;
1001    /// # #[cfg(feature = "ipnet")]
1002    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
1003    ///
1004    /// # #[cfg(feature = "ipnet")]
1005    /// # {
1006    /// let mut map: PrefixMap<ipnet::Ipv4Net, &'static str> = PrefixMap::from_iter([
1007    ///     (net!("1.0.0.0/8"), "a"),
1008    ///     (net!("1.0.0.0/9"), "b"),
1009    ///     (net!("1.128.0.0/9"), "c"),
1010    ///     (net!("1.128.0.0/10"), "d"),
1011    /// ]);
1012    ///
1013    /// let view_at_a = map.view_mut_at(net!("1.0.0.0/8")).unwrap();
1014    /// assert_eq!(view_at_a.value(), Some(&"a"));
1015    ///
1016    /// let (Some(view_at_b), Some(view_at_c)) = view_at_a.split() else { unreachable!() };
1017    /// assert_eq!(view_at_b.value(), Some(&"b"));
1018    /// assert_eq!(view_at_c.value(), Some(&"c"));
1019    ///
1020    /// let (Some(view_at_d), None) = view_at_c.split() else { unreachable!() };
1021    /// assert_eq!(view_at_d.value(), Some(&"d"));
1022    /// # }
1023    /// ```
1024    pub fn split(self) -> (Option<Self>, Option<Self>) {
1025        let (left, right) = match &self.loc {
1026            ViewLoc::Node(idx) => (self.table[*idx].left, self.table[*idx].right),
1027            ViewLoc::Virtual(p, idx) => {
1028                // check if the node is on the right or the left of the virtual one.
1029                if to_right(p, &self.table[*idx].prefix) {
1030                    (None, Some(*idx))
1031                } else {
1032                    (Some(*idx), None)
1033                }
1034            }
1035        };
1036
1037        // Safety: We assume `self` was created while satisfying the safety conditions from
1038        // `TrieViewMut::new`. Thus, `self` is the only TrieView referencing that root. Here, we
1039        // construct two new `TrieViewMut`s, one on the left and one on the right. Thus, they are
1040        // siblings and don't overlap. Further, we destroy `self`, ensuring that the safety
1041        // guarantees remain satisfied.
1042        unsafe {
1043            (
1044                left.map(|idx| Self::new(self.table, ViewLoc::Node(idx))),
1045                right.map(|idx| Self::new(self.table, ViewLoc::Node(idx))),
1046            )
1047        }
1048    }
1049}
1050
1051impl<P, T> TrieViewMut<'_, P, T> {
1052    /// Iterate over all elements in the given view (including the element itself), in
1053    /// lexicographic order, with a mutable reference to the value.
1054    ///
1055    /// ```
1056    /// # use prefix_trie::*;
1057    /// # #[cfg(feature = "ipnet")]
1058    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
1059    ///
1060    /// # #[cfg(feature = "ipnet")]
1061    /// # {
1062    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
1063    ///     (net!("1.0.0.0/8"), 1),
1064    ///     (net!("1.0.0.0/16"), 2),
1065    ///     (net!("1.0.1.0/24"), 3),
1066    ///     (net!("1.1.0.0/16"), 4),
1067    /// ]);
1068    ///
1069    /// map.view_mut_at(net!("1.0.0.0/16")).unwrap().iter_mut().for_each(|(_, x)| *x *= 10);
1070    /// assert_eq!(
1071    ///     map.into_iter().collect::<Vec<_>>(),
1072    ///     vec![
1073    ///         (net!("1.0.0.0/8"), 1),
1074    ///         (net!("1.0.0.0/16"), 20),
1075    ///         (net!("1.0.1.0/24"), 30),
1076    ///         (net!("1.1.0.0/16"), 4),
1077    ///     ]
1078    /// );
1079    /// # }
1080    /// ```
1081    pub fn iter_mut(&mut self) -> IterMut<'_, P, T> {
1082        // Safety: Here, we assume the TrieView was created using the `TrieViewMut::new` function,
1083        // and that the safety conditions from that function were satisfied. These safety conditions
1084        // comply with the safety conditions from `IterMut::new()`. Further, `self` is borrowed
1085        // mutably for the lifetime of the mutable iterator.
1086        unsafe { IterMut::new(self.table, vec![self.loc.idx()]) }
1087    }
1088
1089    /// Iterate over mutable references to all values in the given view (including the element
1090    /// itself), in lexicographic order.
1091    ///
1092    /// ```
1093    /// # use prefix_trie::*;
1094    /// # #[cfg(feature = "ipnet")]
1095    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
1096    ///
1097    /// # #[cfg(feature = "ipnet")]
1098    /// # {
1099    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
1100    ///     (net!("192.168.0.0/20"), 1),
1101    ///     (net!("192.168.0.0/22"), 2),
1102    ///     (net!("192.168.0.0/24"), 3),
1103    ///     (net!("192.168.2.0/23"), 4),
1104    /// ]);
1105    ///
1106    /// map.view_mut_at(net!("192.168.0.0/22")).unwrap().values_mut().for_each(|x| *x *= 10);
1107    /// assert_eq!(
1108    ///     map.into_iter().collect::<Vec<_>>(),
1109    ///     vec![
1110    ///         (net!("192.168.0.0/20"), 1),
1111    ///         (net!("192.168.0.0/22"), 20),
1112    ///         (net!("192.168.0.0/24"), 30),
1113    ///         (net!("192.168.2.0/23"), 40),
1114    ///     ]
1115    /// );
1116    /// # }
1117    /// ```
1118    pub fn values_mut(&mut self) -> ValuesMut<'_, P, T> {
1119        ValuesMut {
1120            inner: self.iter_mut(),
1121        }
1122    }
1123
1124    /// Get a reference to the prefix that is currently pointed at. This prefix might not exist
1125    /// explicitly in the map/set. Instead, it might be a branching or a virtual node. In both
1126    /// cases, this function returns the prefix of that node.
1127    ///
1128    /// ```
1129    /// # use prefix_trie::*;
1130    /// # #[cfg(feature = "ipnet")]
1131    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
1132    ///
1133    /// # #[cfg(feature = "ipnet")]
1134    /// # {
1135    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
1136    ///     (net!("1.0.0.0/20"), 1),
1137    ///     (net!("1.0.0.0/22"), 2),
1138    /// ]);
1139    ///
1140    /// assert_eq!(map.view_mut_at(net!("1.0.0.0/20")).unwrap().prefix(), &net!("1.0.0.0/20"));
1141    /// assert_eq!(map.view_mut_at(net!("1.0.0.0/21")).unwrap().prefix(), &net!("1.0.0.0/21"));
1142    /// assert_eq!(map.view_mut_at(net!("1.0.0.0/22")).unwrap().prefix(), &net!("1.0.0.0/22"));
1143    /// # }
1144    /// ```
1145    pub fn prefix(&self) -> &P {
1146        match &self.loc {
1147            ViewLoc::Node(idx) => &self.table[*idx].prefix,
1148            ViewLoc::Virtual(p, _) => p,
1149        }
1150    }
1151
1152    /// Get a reference to the value at the root of the current view. This function may return
1153    /// `None` if `self` is pointing at a branching or a virtual node.
1154    ///
1155    /// ```
1156    /// # use prefix_trie::*;
1157    /// # #[cfg(feature = "ipnet")]
1158    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
1159    ///
1160    /// # #[cfg(feature = "ipnet")]
1161    /// # {
1162    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
1163    ///     (net!("1.0.0.0/20"), 1),
1164    ///     (net!("1.0.0.0/22"), 2),
1165    /// ]);
1166    ///
1167    /// assert_eq!(map.view_mut_at(net!("1.0.0.0/20")).unwrap().value(), Some(&1));
1168    /// assert_eq!(map.view_mut_at(net!("1.0.0.0/21")).unwrap().value(), None);
1169    /// assert_eq!(map.view_mut_at(net!("1.0.0.0/22")).unwrap().value(), Some(&2));
1170    /// # }
1171    /// ```
1172    pub fn value(&self) -> Option<&T> {
1173        match &self.loc {
1174            ViewLoc::Node(idx) => self.table[*idx].value.as_ref(),
1175            ViewLoc::Virtual(_, _) => None,
1176        }
1177    }
1178
1179    fn node_mut(&mut self) -> Option<&mut Node<P, T>> {
1180        // Safety: In the following, we assume that the safety conditions of `TrieViewMut::new` were
1181        // satisfied. In that case, we know that we are the only ones owning a mutable reference to
1182        // a tree that contains that root node. Therefore, it is safe to take a mutable reference of
1183        // that value.
1184        match &self.loc {
1185            ViewLoc::Node(idx) => unsafe { Some(self.table.get_mut(*idx)) },
1186            ViewLoc::Virtual(_, _) => None,
1187        }
1188    }
1189
1190    /// Get a mutable reference to the value at the root of the current view. This function may
1191    /// return `None` if `self` is pointing at a branching node.
1192    ///
1193    /// ```
1194    /// # use prefix_trie::*;
1195    /// # #[cfg(feature = "ipnet")]
1196    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
1197    ///
1198    /// # #[cfg(feature = "ipnet")]
1199    /// # {
1200    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
1201    ///     (net!("1.0.0.0/20"), 1),
1202    ///     (net!("1.0.0.0/22"), 2),
1203    /// ]);
1204    /// *map.view_mut_at(net!("1.0.0.0/22")).unwrap().value_mut().unwrap() *= 10;
1205    /// assert_eq!(Vec::from_iter(map), vec![(net!("1.0.0.0/20"), 1), (net!("1.0.0.0/22"), 20)]);
1206    /// # }
1207    /// ```
1208    pub fn value_mut(&mut self) -> Option<&mut T> {
1209        self.node_mut()?.value.as_mut()
1210    }
1211
1212    /// Get a reference to both the prefix and the value. This function may return `None` if either
1213    /// `self` is pointing at a branching node.
1214    ///
1215    /// ```
1216    /// # use prefix_trie::*;
1217    /// # #[cfg(feature = "ipnet")]
1218    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
1219    ///
1220    /// # #[cfg(feature = "ipnet")]
1221    /// # {
1222    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
1223    ///     (net!("192.168.0.0/20"), 1),
1224    ///     (net!("192.168.0.0/22"), 2),
1225    /// ]);
1226    ///
1227    /// assert_eq!(
1228    ///     map.view_mut_at(net!("192.168.0.0/20")).unwrap().prefix_value(),
1229    ///     Some((&net!("192.168.0.0/20"), &1))
1230    /// );
1231    /// assert_eq!(map.view_mut_at(net!("192.168.0.0/21")).unwrap().prefix_value(), None);
1232    /// # }
1233    /// ```
1234    pub fn prefix_value(&self) -> Option<(&P, &T)> {
1235        match &self.loc {
1236            ViewLoc::Node(idx) => self.table[*idx].prefix_value(),
1237            ViewLoc::Virtual(_, _) => None,
1238        }
1239    }
1240
1241    /// Get a reference to both the prefix and the value (the latter is mutable). This function may
1242    /// return `None` if either `self` is pointing at a branching node.
1243    ///
1244    /// ```
1245    /// # use prefix_trie::*;
1246    /// # #[cfg(feature = "ipnet")]
1247    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
1248    ///
1249    /// # #[cfg(feature = "ipnet")]
1250    /// # {
1251    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
1252    ///     (net!("1.0.0.0/20"), 1),
1253    ///     (net!("1.0.0.0/22"), 2),
1254    /// ]);
1255    /// *map.view_mut_at(net!("1.0.0.0/22")).unwrap().prefix_value_mut().unwrap().1 *= 10;
1256    /// assert_eq!(Vec::from_iter(map), vec![(net!("1.0.0.0/20"), 1), (net!("1.0.0.0/22"), 20)]);
1257    /// # }
1258    /// ```
1259    pub fn prefix_value_mut(&mut self) -> Option<(&P, &mut T)> {
1260        self.node_mut()?.prefix_value_mut()
1261    }
1262
1263    /// Remove the element at the current position of the view. The tree structure is not modified
1264    /// (similar to calling [`PrefixMap::remove_keep_tree`].)
1265    ///
1266    /// ```
1267    /// # use prefix_trie::*;
1268    /// # #[cfg(feature = "ipnet")]
1269    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
1270    ///
1271    /// # #[cfg(feature = "ipnet")]
1272    /// # {
1273    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
1274    ///     (net!("192.168.0.0/20"), 1),
1275    ///     (net!("192.168.0.0/22"), 2),
1276    ///     (net!("192.168.0.0/24"), 3),
1277    ///     (net!("192.168.2.0/23"), 4),
1278    ///     (net!("192.168.4.0/22"), 5),
1279    /// ]);
1280    /// let mut view = map.view_mut_at(net!("192.168.0.0/22")).unwrap();
1281    /// assert_eq!(view.remove(), Some(2));
1282    /// assert_eq!(
1283    ///     view.into_iter().collect::<Vec<_>>(),
1284    ///     vec![
1285    ///         (&net!("192.168.0.0/24"), &mut 3),
1286    ///         (&net!("192.168.2.0/23"), &mut 4),
1287    ///     ]
1288    /// );
1289    /// assert_eq!(
1290    ///     map.into_iter().collect::<Vec<_>>(),
1291    ///     vec![
1292    ///         (net!("192.168.0.0/20"), 1),
1293    ///         (net!("192.168.0.0/24"), 3),
1294    ///         (net!("192.168.2.0/23"), 4),
1295    ///         (net!("192.168.4.0/22"), 5),
1296    ///     ]
1297    /// );
1298    /// # }
1299    /// ```
1300    pub fn remove(&mut self) -> Option<T> {
1301        self.node_mut()?.value.take()
1302    }
1303
1304    /// Set the value of the node currently pointed at. This operation fails if the current view
1305    /// points at a virtual node, returning `Err(value)`. In such a case, you may want to go to the
1306    /// next node (e.g., using [`TrieViewMut::split`]).
1307    ///
1308    /// This operation will only modify the value, and keep the prefix unchanged (in contrast to
1309    /// `PrefixMap::insert`).
1310    ///
1311    /// This is an implementation detail of mutable views. Since you can have multiple different
1312    /// mutable views pointing to different parts in the tree, it is not safe to modify the tree
1313    /// structure itself.
1314    ///
1315    /// ```
1316    /// # use prefix_trie::*;
1317    /// # #[cfg(feature = "ipnet")]
1318    /// macro_rules! net { ($x:literal) => {$x.parse::<ipnet::Ipv4Net>().unwrap()}; }
1319    ///
1320    /// # #[cfg(feature = "ipnet")]
1321    /// # {
1322    /// let mut map: PrefixMap<ipnet::Ipv4Net, usize> = PrefixMap::from_iter([
1323    ///     (net!("192.168.0.0/20"), 1),
1324    ///     (net!("192.168.0.0/22"), 2),
1325    ///     (net!("192.168.0.0/24"), 3),
1326    ///     (net!("192.168.2.0/23"), 4),
1327    ///     (net!("192.168.4.0/22"), 5),
1328    /// ]);
1329    /// let mut view = map.view_mut_at(net!("192.168.0.0/22")).unwrap();
1330    /// assert_eq!(view.set(20), Ok(Some(2)));
1331    /// assert_eq!(
1332    ///     view.into_iter().collect::<Vec<_>>(),
1333    ///     vec![
1334    ///         (&net!("192.168.0.0/22"), &mut 20),
1335    ///         (&net!("192.168.0.0/24"), &mut 3),
1336    ///         (&net!("192.168.2.0/23"), &mut 4),
1337    ///     ]
1338    /// );
1339    /// assert_eq!(
1340    ///     map.into_iter().collect::<Vec<_>>(),
1341    ///     vec![
1342    ///         (net!("192.168.0.0/20"), 1),
1343    ///         (net!("192.168.0.0/22"), 20),
1344    ///         (net!("192.168.0.0/24"), 3),
1345    ///         (net!("192.168.2.0/23"), 4),
1346    ///         (net!("192.168.4.0/22"), 5),
1347    ///     ]
1348    /// );
1349    /// # }
1350    /// ```
1351    pub fn set(&mut self, value: T) -> Result<Option<T>, T> {
1352        match self.node_mut() {
1353            Some(n) => Ok(n.value.replace(value)),
1354            None => Err(value),
1355        }
1356    }
1357}
1358
1359impl<'a, P, T> IntoIterator for TrieViewMut<'a, P, T> {
1360    type Item = (&'a P, &'a mut T);
1361    type IntoIter = IterMut<'a, P, T>;
1362
1363    fn into_iter(self) -> Self::IntoIter {
1364        // Safety: Here, we assume the TrieView was created using the `TrieViewMut::new` function,
1365        // and that the safety conditions from that function were satisfied. These safety conditions
1366        // comply with the safety conditions from `IterMut::new()`.
1367        unsafe { IterMut::new(self.table, vec![self.loc.idx()]) }
1368    }
1369}
1370
1371mod difference;
1372mod intersection;
1373mod union;
1374pub use difference::{
1375    CoveringDifference, CoveringDifferenceMut, Difference, DifferenceItem, DifferenceMut,
1376    DifferenceMutItem,
1377};
1378pub use intersection::{Intersection, IntersectionMut};
1379pub use union::{Union, UnionItem, UnionMut};