Skip to main content

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