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}