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