ip/traits/prefix/set.rs
1use core::fmt::Debug;
2use core::ops::{Add, BitAnd, BitOr, BitXor, Mul, Not, Sub};
3
4use num_traits::{One, Zero};
5
6use super::{Prefix, Range};
7
8/// Address-family independent interface for IP prefix-sets
9///
10/// Methods on `PrefixSet` types that are well defined for all address-families
11/// are implemented via this trait.
12///
13/// See also [`concrete::PrefixSet<A>`][crate::concrete::PrefixSet] and
14/// [`any::PrefixSet`][crate::any::PrefixSet] for address-family specific items.
15#[allow(clippy::trait_duplication_in_bounds)]
16pub trait Set<'a>:
17 Debug
18 + Clone
19 + Default
20 + Extend<Self::Prefix>
21 + FromIterator<Self::Prefix>
22 + Extend<Self::Range>
23 + FromIterator<Self::Range>
24 + One
25 + Zero
26 + PartialEq
27 + Eq
28 + PartialOrd
29 + BitAnd<Output = Self>
30 + BitOr<Output = Self>
31 + BitXor<Output = Self>
32 + Not<Output = Self>
33 + Add<Output = Self>
34 + Mul<Output = Self>
35 + Sub<Output = Self>
36{
37 /// The type of IP prefix over which `Self` represents a set.
38 type Prefix: Prefix;
39
40 /// The type of IP prefix-range over which `Self` represents a set.
41 type Range: Range<Prefix = Self::Prefix>;
42
43 /// The iterator returned by [`Self::prefixes`].
44 type Prefixes: Iterator<Item = Self::Prefix>;
45
46 /// The iterator returned by [`Self::ranges`].
47 type Ranges: Iterator<Item = Self::Range>;
48
49 /// Test whether `prefix` is contained in `self`.
50 ///
51 /// ```
52 /// # use ip::{traits::PrefixSet as _, Error, Ipv4, Prefix, PrefixRange, PrefixSet};
53 /// let set: PrefixSet<Ipv4> = ["192.0.2.0/24,26,26".parse::<PrefixRange<Ipv4>>()?]
54 /// .into_iter()
55 /// .collect();
56 /// assert!(set.contains("192.0.2.128/26".parse()?));
57 /// # Ok::<_, Error>(())
58 /// ```
59 fn contains(&self, prefix: Self::Prefix) -> bool;
60
61 /// Get an iterator over the [`Self::Prefix`]s contained in `self`.
62 ///
63 /// ```
64 /// # use core::str::FromStr;
65 /// # use ip::{traits::PrefixSet as _, Any, Error, Prefix, PrefixSet};
66 /// let set: PrefixSet<Any> = ["192.0.2.0/25", "192.0.2.128/25"]
67 /// .into_iter()
68 /// .map(Prefix::<Any>::from_str)
69 /// .collect::<Result<_, _>>()?;
70 /// let mut prefixes = set.prefixes();
71 /// assert_eq!(prefixes.next(), Some("192.0.2.0/25".parse()?));
72 /// assert_eq!(prefixes.next(), Some("192.0.2.128/25".parse()?));
73 /// assert_eq!(prefixes.next(), None);
74 /// # Ok::<_, Error>(())
75 /// ```
76 fn prefixes(&'a self) -> Self::Prefixes;
77
78 /// Get an iterator over the [`Self::Range`]s contained in `self`.
79 ///
80 /// ```
81 /// # use core::str::FromStr;
82 /// # use ip::{traits::PrefixSet as _, Any, Error, Prefix, PrefixSet};
83 /// let set: PrefixSet<Any> = ["192.0.2.0/25", "192.0.2.128/25"]
84 /// .into_iter()
85 /// .map(Prefix::<Any>::from_str)
86 /// .collect::<Result<_, _>>()?;
87 /// let mut ranges = set.ranges();
88 /// assert_eq!(ranges.next(), Some("192.0.2.0/24,25,25".parse()?));
89 /// assert_eq!(ranges.next(), None);
90 /// # Ok::<_, Error>(())
91 /// ```
92 fn ranges(&'a self) -> Self::Ranges;
93
94 /// Construct a prefix-set consisting of all prefixes.
95 ///
96 /// ```
97 /// # use core::str::FromStr;
98 /// # use ip::{traits::PrefixSet as _, Any, Error, Prefix, PrefixSet};
99 /// let set = PrefixSet::<Any>::any();
100 /// let mut ranges = set.ranges();
101 /// assert_eq!(ranges.next(), Some("0.0.0.0/0,0,32".parse()?));
102 /// assert_eq!(ranges.next(), Some("::/0,0,128".parse()?));
103 /// assert_eq!(ranges.next(), None);
104 /// # Ok::<_, Error>(())
105 /// ```
106 #[must_use]
107 fn any() -> Self {
108 Self::one()
109 }
110
111 /// Get the number of prefixes in `self`.
112 ///
113 /// ```
114 /// # use ip::{PrefixSet, traits::PrefixSet as _, Error, Ipv4, PrefixRange};
115 /// let set: PrefixSet<Ipv4> = ["192.0.2.0/24,26,26".parse::<PrefixRange<Ipv4>>()?]
116 /// .into_iter()
117 /// .collect();
118 /// assert_eq!(set.len(), 4);
119 /// # Ok::<_, Error>(())
120 /// ```
121 #[must_use]
122 fn len(&'a self) -> usize {
123 self.prefixes().count()
124 }
125
126 /// Test whether `self` is empty.
127 ///
128 /// ``` rust
129 /// # use ip::{traits::PrefixSet as _, Error, Ipv6, PrefixSet};
130 /// assert!(PrefixSet::<Ipv6>::default().is_empty());
131 /// # Ok::<_, Error>(())
132 /// ```
133 #[must_use]
134 fn is_empty(&'a self) -> bool {
135 self.ranges().count() == 0
136 }
137}