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}