Skip to main content

prefix_trie/
set.rs

1//! Prefix set implemented on top of [`PrefixMap`].
2
3use std::fmt::{Debug, Formatter, Result as FmtResult};
4
5use crate::{allocator::Loc, Prefix};
6
7use super::{
8    map::{CoverKeys, PrefixMap},
9    trieview::{AsView, TrieRef, TrieRefMut, TrieView},
10};
11
12/// Set of prefixes, organized in a dense prefix trie.
13///
14/// This structure gives efficient access to the longest prefix in the set that contains another
15/// prefix. Prefixes returned from this set are reconstructed from the trie and are therefore
16/// returned by value. Host bits outside the prefix length are not preserved.
17///
18/// You can perform union, intersection, and difference operations by creating a view with
19/// [`AsView`].
20#[derive(Clone)]
21pub struct PrefixSet<P>(pub(crate) PrefixMap<P, ()>);
22
23impl<P: Prefix> PrefixSet<P> {
24    /// Create a new, empty prefix set.
25    ///
26    /// ```
27    /// use prefix_trie::PrefixSet;
28    ///
29    /// # #[cfg(feature = "ipnet")]
30    /// # {
31    /// let set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
32    /// assert!(set.is_empty());
33    /// # }
34    /// ```
35    pub fn new() -> Self {
36        Self(Default::default())
37    }
38
39    /// Returns the number of prefixes stored in the set.
40    ///
41    /// This is the number of stored prefixes, not the number of addresses they cover (see
42    /// [`address_count`](Self::address_count)).
43    ///
44    /// ```
45    /// use prefix_trie::PrefixSet;
46    ///
47    /// # #[cfg(feature = "ipnet")]
48    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
49    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
50    /// assert_eq!(set.len(), 0);
51    /// set.insert("192.168.0.0/24".parse()?);
52    /// set.insert("192.168.1.0/24".parse()?);
53    /// assert_eq!(set.len(), 2);
54    /// # Ok(())
55    /// # }
56    /// # #[cfg(not(feature = "ipnet"))]
57    /// # fn main() {}
58    /// ```
59    #[inline(always)]
60    pub fn len(&self) -> usize {
61        self.0.len()
62    }
63
64    /// Returns `true` if the set contains no prefixes.
65    ///
66    /// ```
67    /// use prefix_trie::PrefixSet;
68    ///
69    /// # #[cfg(feature = "ipnet")]
70    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
71    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
72    /// assert!(set.is_empty());
73    /// set.insert("192.168.0.0/24".parse()?);
74    /// assert!(!set.is_empty());
75    /// # Ok(())
76    /// # }
77    /// # #[cfg(not(feature = "ipnet"))]
78    /// # fn main() {}
79    /// ```
80    #[inline(always)]
81    pub fn is_empty(&self) -> bool {
82        self.0.is_empty()
83    }
84
85    /// Returns the amount of memory used by this data structure in bytes.
86    ///
87    /// ```
88    /// use prefix_trie::PrefixSet;
89    ///
90    /// # #[cfg(feature = "ipnet")]
91    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
92    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
93    /// let before = set.mem_size();
94    /// set.insert("192.168.0.0/24".parse()?);
95    /// assert!(set.mem_size() >= before);
96    /// # Ok(())
97    /// # }
98    /// # #[cfg(not(feature = "ipnet"))]
99    /// # fn main() {}
100    /// ```
101    pub fn mem_size(&self) -> usize {
102        self.0.mem_size()
103    }
104
105    /// Count the number of unique addresses covered by all prefixes in the set. If the entire trie
106    /// is covered, the function returns `None` (as it contains `P::R::MAX + 1` addresses).
107    /// Overlapping prefixes are not double-counted.
108    ///
109    /// To avoid double-counting, the function traverses the (partial) tree once, skipping nodes
110    /// that are already covered.
111    ///
112    /// ```
113    /// use prefix_trie::PrefixSet;
114    ///
115    /// # #[cfg(feature = "ipnet")]
116    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
117    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
118    /// set.insert("192.0.2.0/24".parse()?);
119    /// set.insert("198.51.100.0/24".parse()?);
120    /// assert_eq!(set.address_count(), Some(512));
121    ///
122    /// // Full address spaces cannot be represented in their address type.
123    /// set.insert("0.0.0.0/0".parse()?);
124    /// assert_eq!(set.address_count(), None);
125    /// # Ok(())
126    /// # }
127    /// # #[cfg(not(feature = "ipnet"))]
128    /// # fn main() {}
129    /// ```
130    pub fn address_count(&self) -> Option<P::R> {
131        self.0.address_count()
132    }
133
134    /// Check whether `prefix` is present in the set.
135    ///
136    /// ```
137    /// use prefix_trie::PrefixSet;
138    ///
139    /// # #[cfg(feature = "ipnet")]
140    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
141    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
142    /// set.insert("192.168.1.0/24".parse()?);
143    /// assert!(set.contains(&"192.168.1.0/24".parse()?));
144    /// assert!(!set.contains(&"192.168.2.0/24".parse()?));
145    /// assert!(!set.contains(&"192.168.0.0/23".parse()?));
146    /// assert!(!set.contains(&"192.168.1.128/25".parse()?));
147    /// # Ok(())
148    /// # }
149    /// # #[cfg(not(feature = "ipnet"))]
150    /// # fn main() {}
151    /// ```
152    pub fn contains(&self, prefix: &P) -> bool {
153        self.0.contains_key(prefix)
154    }
155
156    /// Get the canonical (reconstructed) prefix that matches `prefix` exactly.
157    ///
158    /// Prefixes are not stored verbatim. They are reconstructed from the trie position, so host
159    /// bits masked out by the prefix length are not preserved.
160    pub fn get(&self, prefix: &P) -> Option<P> {
161        self.0.get_key_value(prefix).map(|(p, _)| p)
162    }
163
164    /// Get the longest prefix in the set that contains `prefix`.
165    ///
166    /// ```
167    /// use prefix_trie::PrefixSet;
168    ///
169    /// # #[cfg(feature = "ipnet")]
170    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
171    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
172    /// set.insert("192.168.1.0/24".parse()?);
173    /// set.insert("192.168.0.0/23".parse()?);
174    /// assert_eq!(set.get_lpm(&"192.168.1.1/32".parse()?), Some("192.168.1.0/24".parse()?));
175    /// assert_eq!(set.get_lpm(&"192.168.1.0/24".parse()?), Some("192.168.1.0/24".parse()?));
176    /// assert_eq!(set.get_lpm(&"192.168.0.0/24".parse()?), Some("192.168.0.0/23".parse()?));
177    /// assert_eq!(set.get_lpm(&"192.168.2.0/24".parse()?), None);
178    /// # Ok(())
179    /// # }
180    /// # #[cfg(not(feature = "ipnet"))]
181    /// # fn main() {}
182    /// ```
183    pub fn get_lpm(&self, prefix: &P) -> Option<P> {
184        self.0.get_lpm_prefix(prefix)
185    }
186
187    /// Get the shortest prefix in the set that contains `prefix`.
188    ///
189    /// ```
190    /// use prefix_trie::PrefixSet;
191    ///
192    /// # #[cfg(feature = "ipnet")]
193    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
194    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
195    /// set.insert("192.168.1.0/24".parse()?);
196    /// set.insert("192.168.0.0/23".parse()?);
197    /// assert_eq!(set.get_spm(&"192.168.1.1/32".parse()?), Some("192.168.0.0/23".parse()?));
198    /// assert_eq!(set.get_spm(&"192.168.1.0/24".parse()?), Some("192.168.0.0/23".parse()?));
199    /// assert_eq!(set.get_spm(&"192.168.0.0/23".parse()?), Some("192.168.0.0/23".parse()?));
200    /// assert_eq!(set.get_spm(&"192.168.2.0/24".parse()?), None);
201    /// # Ok(())
202    /// # }
203    /// # #[cfg(not(feature = "ipnet"))]
204    /// # fn main() {}
205    /// ```
206    pub fn get_spm(&self, prefix: &P) -> Option<P> {
207        self.0.get_spm_prefix(prefix)
208    }
209
210    /// Check whether `prefix` is covered by the set, i.e., whether the set contains `prefix` itself
211    /// or any less-specific prefix that contains it.
212    ///
213    /// This is equivalent to `self.cover(prefix).next().is_some()`, but stops at the first (shortest)
214    /// covering prefix. See [`cover`](Self::cover) to iterate over the covering prefixes themselves.
215    ///
216    /// This function does not perform aggregation. That means that, even if both the left and right
217    /// children of `p` are present in the set, `is_covered(p)` may still return `false`. See
218    /// [`is_covered_in_aggregate`](Self::is_covered_in_aggregate) for that case.
219    ///
220    /// ```
221    /// use prefix_trie::PrefixSet;
222    ///
223    /// # #[cfg(feature = "ipnet")]
224    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
225    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
226    /// set.insert("10.0.0.0/8".parse()?);
227    /// assert!(set.is_covered(&"10.0.0.0/8".parse()?));  // exact member
228    /// assert!(set.is_covered(&"10.1.2.0/24".parse()?)); // covered by 10.0.0.0/8
229    /// assert!(!set.is_covered(&"11.0.0.0/8".parse()?)); // not covered
230    /// # Ok(())
231    /// # }
232    /// # #[cfg(not(feature = "ipnet"))]
233    /// # fn main() {}
234    /// ```
235    #[inline(always)]
236    pub fn is_covered(&self, prefix: &P) -> bool {
237        self.0.is_covered(prefix)
238    }
239
240    /// Check whether every address in `prefix` is covered by the set, i.e., whether `prefix`'s
241    /// entire range is tiled by members of the set, even if no single member covers `prefix` on
242    /// its own.
243    ///
244    /// This is equivalent to `{ let mut s = self.clone(); s.aggregate(); s.is_covered(prefix) }`,
245    /// but read-only and without cloning. See [`is_covered`](Self::is_covered) for the (cheaper,
246    /// stricter) single-member check.
247    ///
248    /// ```
249    /// use prefix_trie::PrefixSet;
250    ///
251    /// # #[cfg(feature = "ipnet")]
252    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
253    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
254    /// set.insert("10.0.0.0/9".parse()?);
255    /// set.insert("10.128.0.0/9".parse()?);
256    /// assert!(!set.is_covered(&"10.0.0.0/8".parse()?));             // no single covering member
257    /// assert!(set.is_covered_in_aggregate(&"10.0.0.0/8".parse()?)); // the two /9s tile the /8
258    /// # Ok(())
259    /// # }
260    /// # #[cfg(not(feature = "ipnet"))]
261    /// # fn main() {}
262    /// ```
263    #[inline(always)]
264    pub fn is_covered_in_aggregate(&self, prefix: &P) -> bool {
265        self.0.is_covered_in_aggregate(prefix)
266    }
267
268    /// Adds a prefix to the set.
269    ///
270    /// Returns whether the prefix was newly inserted.
271    ///
272    /// ```
273    /// use prefix_trie::PrefixSet;
274    ///
275    /// # #[cfg(feature = "ipnet")]
276    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
277    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
278    /// assert!(set.insert("192.168.0.0/23".parse()?));
279    /// assert!(set.insert("192.168.1.0/24".parse()?));
280    /// assert!(!set.insert("192.168.1.0/24".parse()?));
281    /// # Ok(())
282    /// # }
283    /// # #[cfg(not(feature = "ipnet"))]
284    /// # fn main() {}
285    /// ```
286    pub fn insert(&mut self, prefix: P) -> bool {
287        self.0.insert(prefix, ()).is_none()
288    }
289
290    /// Removes `prefix` from the set and returns whether it was present.
291    ///
292    /// ```
293    /// use prefix_trie::PrefixSet;
294    ///
295    /// # #[cfg(feature = "ipnet")]
296    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
297    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
298    /// let prefix = "192.168.1.0/24".parse()?;
299    /// set.insert(prefix);
300    /// assert!(set.contains(&prefix));
301    /// assert!(set.remove(&prefix));
302    /// assert!(!set.contains(&prefix));
303    /// # Ok(())
304    /// # }
305    /// # #[cfg(not(feature = "ipnet"))]
306    /// # fn main() {}
307    /// ```
308    pub fn remove(&mut self, prefix: &P) -> bool {
309        self.0.remove(prefix).is_some()
310    }
311
312    /// Removes `prefix` from the set and may leave empty trie nodes in place.
313    ///
314    /// ```
315    /// use prefix_trie::PrefixSet;
316    ///
317    /// # #[cfg(feature = "ipnet")]
318    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
319    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
320    /// let prefix = "192.168.1.0/24".parse()?;
321    /// set.insert(prefix);
322    /// assert!(set.contains(&prefix));
323    /// assert!(set.remove_keep_tree(&prefix));
324    /// assert!(!set.contains(&prefix));
325    /// # Ok(())
326    /// # }
327    /// # #[cfg(not(feature = "ipnet"))]
328    /// # fn main() {}
329    /// ```
330    pub fn remove_keep_tree(&mut self, prefix: &P) -> bool {
331        self.0.remove_keep_tree(prefix).is_some()
332    }
333
334    /// Remove all prefixes that are contained within `prefix`.
335    ///
336    /// ```
337    /// use prefix_trie::PrefixSet;
338    ///
339    /// # #[cfg(feature = "ipnet")]
340    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
341    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
342    /// set.insert("192.168.0.0/22".parse()?);
343    /// set.insert("192.168.0.0/23".parse()?);
344    /// set.insert("192.168.0.0/24".parse()?);
345    /// set.insert("192.168.2.0/23".parse()?);
346    /// set.insert("192.168.2.0/24".parse()?);
347    /// set.remove_children(&"192.168.0.0/23".parse()?);
348    /// assert!(!set.contains(&"192.168.0.0/23".parse()?));
349    /// assert!(!set.contains(&"192.168.0.0/24".parse()?));
350    /// assert!(set.contains(&"192.168.2.0/23".parse()?));
351    /// assert!(set.contains(&"192.168.2.0/24".parse()?));
352    /// # Ok(())
353    /// # }
354    /// # #[cfg(not(feature = "ipnet"))]
355    /// # fn main() {}
356    /// ```
357    pub fn remove_children(&mut self, prefix: &P) {
358        self.0.remove_children(prefix)
359    }
360
361    /// Clear the set while keeping allocated memory for reuse.
362    ///
363    /// ```
364    /// use prefix_trie::PrefixSet;
365    ///
366    /// # #[cfg(feature = "ipnet")]
367    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
368    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
369    /// set.insert("192.168.0.0/24".parse()?);
370    /// set.insert("192.168.1.0/24".parse()?);
371    /// set.clear();
372    /// assert!(set.is_empty());
373    /// assert!(!set.contains(&"192.168.0.0/24".parse()?));
374    /// # Ok(())
375    /// # }
376    /// # #[cfg(not(feature = "ipnet"))]
377    /// # fn main() {}
378    /// ```
379    pub fn clear(&mut self) {
380        self.0.clear()
381    }
382
383    /// Modifies the prefix set by removing entries that are already covered by another one with a
384    /// shorter prefix length, **without** merging adjacent prefixes.
385    ///
386    /// **Invariant**: for *any* prefix `p`, `before.is_covered(p)` and `after.is_covered(p)` yield
387    /// the same value (while the matched prefix may become less specific).
388    ///
389    /// ```
390    /// use prefix_trie::PrefixSet;
391    ///
392    /// # #[cfg(feature = "ipnet")]
393    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
394    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
395    /// set.insert("10.0.0.0/24".parse()?);
396    /// set.insert("10.0.1.0/24".parse()?);   // adjacent sibling of 10.0.0.0/24
397    /// set.insert("10.0.0.128/25".parse()?); // covered by 10.0.0.0/24
398    /// set.aggregate_consistent();
399    /// // Only the covered /25 is dropped; the two /24 siblings are *not* merged.
400    /// assert_eq!(
401    ///     set.iter().collect::<Vec<_>>(),
402    ///     vec![
403    ///         "10.0.0.0/24".parse()?,
404    ///         "10.0.1.0/24".parse()?,
405    ///     ]
406    /// );
407    /// # Ok(())
408    /// # }
409    /// # #[cfg(not(feature = "ipnet"))]
410    /// # fn main() {}
411    /// ```
412    pub fn aggregate_consistent(&mut self) {
413        // SAFETY: `Loc::root()` is always a valid, live node location.
414        let count_delta = unsafe { self.0.table_mut().aggregate_consistent_set(Loc::root(), 0) };
415        self.0.count = (self.0.count as i64 + count_delta) as usize;
416    }
417
418    /// Modifies the prefix set by removing entries that are already covered by another one with a
419    /// shorter prefix length, and by (recursively) merging adjacent prefixes.
420    ///
421    /// **Invariant**: for any *address* `a` (a host prefix of maximal length),
422    /// `before.is_covered(a) == after.is_covered(a)`. That is, the covered address space is
423    /// preserved exactly. This does **not** extend to shorter prefixes: merging siblings can make
424    /// `get_lpm` return `Some` for a prefix that previously matched nothing. For example, two
425    /// `/24`s merge into a `/23`, so `get_lpm` of that `/23` flips from `None` to `Some`. If you
426    /// need the invariant to hold for every prefix, use [`PrefixSet::aggregate_consistent`], which
427    /// only drops redundant entries and never merges.
428    ///
429    /// ```
430    /// use prefix_trie::PrefixSet;
431    ///
432    /// # #[cfg(feature = "ipnet")]
433    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
434    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
435    /// set.insert("10.0.0.0/24".parse()?);
436    /// set.insert("10.0.1.0/24".parse()?);   // adjacent sibling of 10.0.0.0/24
437    /// set.insert("10.0.0.128/25".parse()?); // covered by 10.0.0.0/24
438    /// set.aggregate();
439    /// // The two /24 siblings are merged into a single /23.
440    /// assert_eq!(
441    ///     set.iter().collect::<Vec<_>>(),
442    ///     vec![
443    ///         "10.0.0.0/23".parse()?,
444    ///     ]
445    /// );
446    /// # Ok(())
447    /// # }
448    /// # #[cfg(not(feature = "ipnet"))]
449    /// # fn main() {}
450    /// ```
451    pub fn aggregate(&mut self) {
452        // SAFETY: `Loc::root()` is always a valid, live node location.
453        let (_, count_delta) = unsafe { self.0.table_mut().aggregate_set(Loc::root(), 0) };
454        self.0.count = (self.0.count as i64 + count_delta) as usize;
455    }
456
457    /// Iterate over all prefixes in lexicographic order.
458    ///
459    /// The iterator yields canonical owned prefixes.
460    ///
461    /// ```
462    /// use prefix_trie::PrefixSet;
463    ///
464    /// # #[cfg(feature = "ipnet")]
465    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
466    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
467    /// set.insert("192.168.0.0/23".parse()?);
468    /// set.insert("192.168.0.0/24".parse()?);
469    /// set.insert("192.168.2.0/23".parse()?);
470    /// assert_eq!(
471    ///     set.iter().collect::<Vec<_>>(),
472    ///     vec![
473    ///         "192.168.0.0/23".parse()?,
474    ///         "192.168.0.0/24".parse()?,
475    ///         "192.168.2.0/23".parse()?,
476    ///     ]
477    /// );
478    /// # Ok(())
479    /// # }
480    /// # #[cfg(not(feature = "ipnet"))]
481    /// # fn main() {}
482    /// ```
483    pub fn iter(&self) -> Iter<'_, P> {
484        self.into_iter()
485    }
486
487    /// Iterate over all prefixes starting at `prefix`, in lexicographic order.
488    ///
489    /// This enables stateless, cursor-based pagination: pass the last-seen prefix to resume.
490    ///
491    /// - If `inclusive` is `true`, the iterator includes `prefix` (if present).
492    /// - If `inclusive` is `false`, the iterator starts after `prefix`. Prefixes more specific than
493    ///   `prefix` (its children) are still yielded.
494    ///
495    /// If `prefix` is not present in the set, the iterator starts at the first prefix that would
496    /// come after `prefix` in lexicographic order, regardless of `inclusive`.
497    ///
498    /// ```
499    /// use prefix_trie::PrefixSet;
500    ///
501    /// # #[cfg(feature = "ipnet")]
502    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
503    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
504    /// set.insert("10.0.0.0/8".parse()?);
505    /// set.insert("10.1.0.0/16".parse()?);
506    /// set.insert("10.2.0.0/16".parse()?);
507    /// set.insert("10.3.0.0/16".parse()?);
508    ///
509    /// // Cursor pagination: skip last seen, fetch next page
510    /// let page: Vec<_> = set.iter_from(&"10.1.0.0/16".parse()?, false).take(2).collect();
511    /// assert_eq!(page, vec!["10.2.0.0/16".parse()?, "10.3.0.0/16".parse()?]);
512    /// # Ok(())
513    /// # }
514    /// # #[cfg(not(feature = "ipnet"))]
515    /// # fn main() {}
516    /// ```
517    pub fn iter_from<'a>(&'a self, prefix: &P, inclusive: bool) -> Iter<'a, P> {
518        Iter(self.0.iter_from(prefix, inclusive))
519    }
520
521    /// Keep only prefixes that satisfy the predicate `f`.
522    ///
523    /// ```
524    /// use prefix_trie::{Prefix, PrefixSet};
525    ///
526    /// # #[cfg(feature = "ipnet")]
527    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
528    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
529    /// set.insert("192.168.0.0/24".parse()?);
530    /// set.insert("192.168.1.0/24".parse()?);
531    /// set.insert("192.168.2.0/24".parse()?);
532    /// set.insert("192.168.2.0/25".parse()?);
533    /// set.retain(|p| p.prefix_len() == 24);
534    /// assert!(set.contains(&"192.168.0.0/24".parse()?));
535    /// assert!(set.contains(&"192.168.1.0/24".parse()?));
536    /// assert!(set.contains(&"192.168.2.0/24".parse()?));
537    /// assert!(!set.contains(&"192.168.2.0/25".parse()?));
538    /// # Ok(())
539    /// # }
540    /// # #[cfg(not(feature = "ipnet"))]
541    /// # fn main() {}
542    /// ```
543    pub fn retain<F>(&mut self, mut f: F)
544    where
545        F: FnMut(&P) -> bool,
546    {
547        self.0.retain(|p, _| f(p));
548    }
549
550    /// Iterate over `prefix` and all more-specific prefixes contained within it, including `prefix`
551    /// itself if it is present.
552    ///
553    /// The iterator yields canonical owned prefixes in lexicographic order.
554    ///
555    /// ```
556    /// use prefix_trie::PrefixSet;
557    ///
558    /// # #[cfg(feature = "ipnet")]
559    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
560    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
561    /// set.insert("192.168.0.0/22".parse()?);
562    /// set.insert("192.168.0.0/23".parse()?);
563    /// set.insert("192.168.2.0/23".parse()?);
564    /// set.insert("192.168.0.0/24".parse()?);
565    /// set.insert("192.168.2.0/24".parse()?);
566    /// assert_eq!(
567    ///     set.children(&"192.168.0.0/23".parse()?).collect::<Vec<_>>(),
568    ///     vec![
569    ///         "192.168.0.0/23".parse()?,
570    ///         "192.168.0.0/24".parse()?,
571    ///     ]
572    /// );
573    /// # Ok(())
574    /// # }
575    /// # #[cfg(not(feature = "ipnet"))]
576    /// # fn main() {}
577    /// ```
578    pub fn children<'a>(&'a self, prefix: &P) -> Iter<'a, P> {
579        Iter(self.0.children(prefix))
580    }
581
582    /// Iterate over all prefixes in the set that cover `prefix`.
583    ///
584    /// This includes `prefix` itself if it is present in the set. The iterator yields canonical
585    /// owned prefixes ordered by prefix length.
586    ///
587    /// ```
588    /// use prefix_trie::PrefixSet;
589    ///
590    /// # #[cfg(feature = "ipnet")]
591    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
592    /// let mut set: PrefixSet<ipnet::Ipv4Net> = PrefixSet::new();
593    /// let p0 = "10.0.0.0/8".parse()?;
594    /// let p1 = "10.1.0.0/16".parse()?;
595    /// let p2 = "10.1.1.0/24".parse()?;
596    /// set.insert(p0);
597    /// set.insert(p1);
598    /// set.insert(p2);
599    /// set.insert("10.1.2.0/24".parse()?);
600    /// set.insert("10.1.1.0/25".parse()?);
601    /// set.insert("11.0.0.0/8".parse()?);
602    /// assert_eq!(set.cover(&p2).collect::<Vec<_>>(), vec![p0, p1, p2]);
603    /// # Ok(())
604    /// # }
605    /// # #[cfg(not(feature = "ipnet"))]
606    /// # fn main() {}
607    /// ```
608    pub fn cover<'a>(&'a self, prefix: &P) -> CoverKeys<'a, P, ()> {
609        self.0.cover_keys(prefix)
610    }
611}
612
613impl<P: Prefix> Default for PrefixSet<P> {
614    fn default() -> Self {
615        Self::new()
616    }
617}
618
619impl<P> PartialEq for PrefixSet<P>
620where
621    P: Prefix,
622{
623    fn eq(&self, other: &Self) -> bool {
624        self.len() == other.len() && self.view().eq_keys(other)
625    }
626}
627
628impl<P> Eq for PrefixSet<P> where P: Prefix {}
629
630impl<P> Debug for PrefixSet<P>
631where
632    P: Prefix + Debug,
633{
634    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
635        f.debug_set().entries(self.iter()).finish()
636    }
637}
638
639/// An iterator over all prefixes of a [`PrefixSet`] in lexicographic order.
640///
641/// This iterator yields canonical owned prefixes.
642#[derive(Clone, Default)]
643pub struct Iter<'a, P: Prefix>(crate::map::Iter<'a, P, ()>);
644
645impl<P: Prefix> Iterator for Iter<'_, P> {
646    type Item = P;
647
648    fn next(&mut self) -> Option<Self::Item> {
649        self.0.next().map(|(p, _)| p)
650    }
651}
652
653/// A consuming iterator over all prefixes of a [`PrefixSet`] in lexicographic order.
654#[derive(Clone)]
655pub struct IntoIter<P: Prefix>(crate::map::IntoIter<P, ()>);
656
657impl<P: Prefix> Iterator for IntoIter<P> {
658    type Item = P;
659
660    fn next(&mut self) -> Option<Self::Item> {
661        self.0.next().map(|(p, _)| p)
662    }
663}
664
665impl<P: Prefix> IntoIterator for PrefixSet<P> {
666    type Item = P;
667
668    type IntoIter = IntoIter<P>;
669
670    fn into_iter(self) -> Self::IntoIter {
671        IntoIter(self.0.into_iter())
672    }
673}
674
675impl<'a, P: Prefix> IntoIterator for &'a PrefixSet<P> {
676    type Item = P;
677
678    type IntoIter = Iter<'a, P>;
679
680    fn into_iter(self) -> Self::IntoIter {
681        Iter(self.0.iter())
682    }
683}
684
685impl<P: Prefix> FromIterator<P> for PrefixSet<P> {
686    fn from_iter<I: IntoIterator<Item = P>>(iter: I) -> Self {
687        let mut set = Self::new();
688        for p in iter {
689            set.insert(p);
690        }
691        set
692    }
693}
694
695impl<'a, P: Prefix> AsView<'a> for &'a PrefixSet<P> {
696    type P = P;
697    type View = TrieRef<'a, P, ()>;
698
699    fn view(self) -> Self::View {
700        TrieRef::new_root(self.0.table())
701    }
702}
703
704impl<'a, P: Prefix> AsView<'a> for &'a mut PrefixSet<P> {
705    type P = P;
706    type View = TrieRefMut<'a, P, ()>;
707
708    fn view(self) -> Self::View {
709        let raw = self.0.table_mut().raw_cells();
710        TrieRefMut::new_root(self.0.table(), raw)
711    }
712}
713
714#[cfg(test)]
715mod tests {
716    use super::*;
717
718    type P = (u32, u8);
719
720    #[test]
721    fn test_default_iter_is_empty() {
722        assert_eq!(Iter::<P>::default().count(), 0);
723    }
724}