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