use crate::{
interfaces::IpAddress,
prefix::IpPrefix,
range::IpRange,
tools::range::{merge_sorted, normalize},
};
pub struct IpSetBuilder<A: IpAddress> {
adds: Vec<IpRange<A>>,
removes: Vec<IpRange<A>>,
}
impl<A: IpAddress> Default for IpSetBuilder<A> {
fn default() -> Self {
Self::new()
}
}
impl<A: IpAddress> IpSetBuilder<A> {
pub fn new() -> Self {
Self { adds: Vec::new(), removes: Vec::new() }
}
pub fn add_ip(&mut self, ip: A) {
let range = IpRange::new(ip, ip);
self.add_range(range);
}
pub fn remove_ip(&mut self, ip: A) {
let range = IpRange::new(ip, ip);
self.remove_range(range);
}
pub fn add_range(&mut self, range: IpRange<A>) {
if range.is_valid() {
self.adds.push(range);
}
}
pub fn remove_range(&mut self, range: IpRange<A>) {
if range.is_valid() {
self.removes.push(range);
}
}
pub fn add_prefix(&mut self, prefix: IpPrefix<A>) {
let range = prefix.to_range();
self.add_range(range);
}
pub fn remove_prefix(&mut self, prefix: IpPrefix<A>) {
let range = prefix.to_range();
self.remove_range(range);
}
pub fn add_ipset(&mut self, other: &IpSet<A>) {
for range in &other.ranges {
self.add_range(*range);
}
}
pub fn remove_ipset(&mut self, other: &IpSet<A>) {
for range in &other.ranges {
self.remove_range(*range);
}
}
#[must_use]
pub fn build(self) -> IpSet<A> {
let adds = IpSet::new(normalize(self.adds));
if self.removes.is_empty() {
return adds;
}
let removes = IpSet::new(normalize(self.removes));
adds.difference(&removes)
}
}
impl<A: IpAddress> FromIterator<IpRange<A>> for IpSetBuilder<A> {
fn from_iter<I: IntoIterator<Item = IpRange<A>>>(iter: I) -> Self {
let mut builder = IpSetBuilder::new();
for range in iter {
builder.add_range(range);
}
builder
}
}
impl<A: IpAddress> FromIterator<IpPrefix<A>> for IpSetBuilder<A> {
fn from_iter<I: IntoIterator<Item = IpPrefix<A>>>(iter: I) -> Self {
let mut builder = IpSetBuilder::new();
for prefix in iter {
builder.add_prefix(prefix);
}
builder
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct IpSet<A: IpAddress> {
ranges: Vec<IpRange<A>>,
}
impl<A: IpAddress> IpSet<A> {
fn new(ranges: Vec<IpRange<A>>) -> Self {
Self { ranges }
}
#[must_use]
pub fn ranges(&self) -> &[IpRange<A>] {
&self.ranges
}
#[must_use]
pub fn prefixes(&self) -> Vec<IpPrefix<A>> {
let mut prefixes = Vec::<IpPrefix<A>>::new();
for range in &self.ranges {
prefixes.extend(range.prefixes());
}
prefixes
}
#[must_use]
pub fn contains_ip(&self, ip: A) -> bool {
self.ranges
.binary_search_by(|range| {
if ip < range.start() {
std::cmp::Ordering::Greater
} else if ip > range.end() {
std::cmp::Ordering::Less
} else {
std::cmp::Ordering::Equal
}
})
.is_ok()
}
#[must_use]
pub fn contains_range(&self, range: IpRange<A>) -> bool {
if !range.is_valid() {
return false;
}
let idx = self.ranges.binary_search_by(|r| {
if range.start() < r.start() {
std::cmp::Ordering::Greater
} else if range.end() > r.end() {
std::cmp::Ordering::Less
} else {
std::cmp::Ordering::Equal
}
});
match idx {
Ok(i) => range.end() <= self.ranges[i].end(),
Err(_) => false,
}
}
#[must_use]
pub fn overlaps_ip_set(&self, other: &IpSet<A>) -> bool {
let mut i = 0;
let mut j = 0;
while i < self.ranges.len() && j < other.ranges.len() {
let a = &self.ranges[i];
let b = &other.ranges[j];
if a.overlaps(b) {
return true;
}
if a.end().to_u128() < b.end().to_u128() {
i += 1;
} else {
j += 1;
}
}
false
}
#[must_use]
pub fn count(&self) -> u128 {
self.ranges.iter().fold(0u128, |acc, r| {
acc.saturating_add(
(r.end().to_u128() - r.start().to_u128()).saturating_add(1),
)
})
}
#[must_use]
pub fn count_checked(&self) -> Option<u128> {
self.ranges.iter().try_fold(0u128, |acc, r| {
let range_count =
(r.end().to_u128() - r.start().to_u128()).checked_add(1)?;
acc.checked_add(range_count)
})
}
#[must_use]
pub fn is_subset_of(&self, other: &IpSet<A>) -> bool {
if self.is_empty() {
return true;
}
if other.is_empty() {
return false;
}
let mut j = 0usize;
for a in &self.ranges {
let a_start = a.start().to_u128();
let a_end = a.end().to_u128();
while j < other.ranges.len() && other.ranges[j].end().to_u128() < a_start {
j += 1;
}
if j >= other.ranges.len()
|| other.ranges[j].start().to_u128() > a_start
|| other.ranges[j].end().to_u128() < a_end
{
return false;
}
}
true
}
#[must_use]
pub fn is_superset_of(&self, other: &IpSet<A>) -> bool {
other.is_subset_of(self)
}
#[must_use]
pub fn len(&self) -> usize {
self.ranges.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.ranges.is_empty()
}
#[must_use]
pub fn union(&self, other: &IpSet<A>) -> IpSet<A> {
let mut merged = Vec::with_capacity(self.ranges.len() + other.ranges.len());
let mut i = 0;
let mut j = 0;
while i < self.ranges.len() && j < other.ranges.len() {
if self.ranges[i].start() <= other.ranges[j].start() {
merged.push(self.ranges[i]);
i += 1;
} else {
merged.push(other.ranges[j]);
j += 1;
}
}
merged.extend_from_slice(&self.ranges[i..]);
merged.extend_from_slice(&other.ranges[j..]);
IpSet::new(merge_sorted(merged))
}
#[must_use]
pub fn difference(&self, other: &IpSet<A>) -> IpSet<A> {
let mut result = Vec::new();
let mut j = 0usize;
for a in &self.ranges {
let mut cur = a.start().to_u128();
let a_end = a.end().to_u128();
let mut consumed = false;
while j < other.ranges.len() && other.ranges[j].end().to_u128() < cur {
j += 1;
}
while j < other.ranges.len() {
let b_start = other.ranges[j].start().to_u128();
let b_end = other.ranges[j].end().to_u128();
if b_start > a_end {
break;
}
if b_start > cur {
result.push(IpRange::new(A::from_u128(cur), A::from_u128(b_start - 1)));
}
if b_end >= a_end {
consumed = true;
break;
}
cur = b_end + 1;
j += 1;
}
if !consumed {
result.push(IpRange::new(A::from_u128(cur), A::from_u128(a_end)));
}
}
IpSet::new(result)
}
#[must_use]
pub fn intersection(&self, other: &IpSet<A>) -> IpSet<A> {
let mut result = Vec::new();
let mut i = 0;
let mut j = 0;
while i < self.ranges.len() && j < other.ranges.len() {
let a = &self.ranges[i];
let b = &other.ranges[j];
let a_start = a.start().to_u128();
let a_end = a.end().to_u128();
let b_start = b.start().to_u128();
let b_end = b.end().to_u128();
if a.overlaps(b) {
let start = A::from_u128(a_start.max(b_start));
let end = A::from_u128(a_end.min(b_end));
result.push(IpRange::new(start, end));
}
if a_end < b_end {
i += 1;
} else if b_end < a_end {
j += 1;
} else {
i += 1;
j += 1;
}
}
IpSet::new(result)
}
#[must_use]
pub fn complement(&self) -> IpSet<A> {
let max_addr = u128::MAX >> (128u32.saturating_sub(A::BITS as u32));
if self.is_empty() {
return IpSet::new(vec![IpRange::new(A::from_u128(0), A::from_u128(max_addr))]);
}
let mut result = Vec::new();
let first_start = self.ranges[0].start().to_u128();
if first_start > 0 {
result.push(IpRange::new(A::from_u128(0), A::from_u128(first_start - 1)));
}
for window in self.ranges.windows(2) {
let prev_end = window[0].end().to_u128();
let next_start = window[1].start().to_u128();
result.push(IpRange::new(
A::from_u128(prev_end + 1),
A::from_u128(next_start - 1),
));
}
let last_end = self.ranges.last().unwrap().end().to_u128();
if last_end < max_addr {
result.push(IpRange::new(
A::from_u128(last_end + 1),
A::from_u128(max_addr),
));
}
IpSet::new(result)
}
}
impl<'a, A: IpAddress> IntoIterator for &'a IpSet<A> {
type Item = &'a IpRange<A>;
type IntoIter = std::slice::Iter<'a, IpRange<A>>;
fn into_iter(self) -> Self::IntoIter {
self.ranges.iter()
}
}
impl<A: IpAddress> IntoIterator for IpSet<A> {
type Item = IpRange<A>;
type IntoIter = std::vec::IntoIter<IpRange<A>>;
fn into_iter(self) -> Self::IntoIter {
self.ranges.into_iter()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::net::{Ipv4Addr, Ipv6Addr};
#[test]
fn test_v4_ipset_default_construction() {
let builder = IpSetBuilder::<Ipv4Addr>::default();
let ipset = builder.build();
assert!(ipset.is_empty());
}
#[test]
fn test_v6_ipset_default_construction() {
let builder = IpSetBuilder::<Ipv6Addr>::default();
let ipset = builder.build();
assert!(ipset.is_empty());
}
#[test]
fn test_v4_ipset_add_range_construction() {
let start = Ipv4Addr::new(192, 168, 0, 0);
let end = Ipv4Addr::new(192, 168, 255, 255);
let range = IpRange::new(start, end);
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(range);
let ipset = builder.build();
assert!(!ipset.is_empty());
assert_eq!(ipset.len(), 1);
}
#[test]
fn test_v4_ipset_multi_add_adjacent_ranges() {
let start1 = Ipv4Addr::new(192, 168, 0, 0);
let end1 = Ipv4Addr::new(192, 168, 255, 255);
let range1 = IpRange::new(start1, end1);
let start2 = Ipv4Addr::new(192, 168, 1, 0);
let end2 = Ipv4Addr::new(192, 168, 255, 255);
let range2 = IpRange::new(start2, end2);
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(range1);
builder.add_range(range2);
let ipset = builder.build();
assert!(!ipset.is_empty());
assert_eq!(ipset.len(), 1);
}
#[test]
fn test_v4_ipset_multi_add_disjoint_ranges() {
let start1 = Ipv4Addr::new(192, 168, 0, 0);
let end1 = Ipv4Addr::new(192, 168, 255, 255);
let range1 = IpRange::new(start1, end1);
let start2 = Ipv4Addr::new(10, 0, 0, 0);
let end2 = Ipv4Addr::new(10, 255, 255, 255);
let range2 = IpRange::new(start2, end2);
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(range1);
builder.add_range(range2);
let ipset = builder.build();
assert!(!ipset.is_empty());
assert_eq!(ipset.len(), 2);
}
#[test]
fn test_v6_ipset_add_range_construction() {
let start = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
let end = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10);
let range = IpRange::new(start, end);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(range);
let ipset = builder.build();
assert!(!ipset.is_empty());
assert_eq!(ipset.len(), 1);
}
#[test]
fn test_v6_ipset_multi_add_adjacent_ranges() {
let start1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
let end1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10);
let range1 = IpRange::new(start1, end1);
let start2 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 11);
let end2 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20);
let range2 = IpRange::new(start2, end2);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(range1);
builder.add_range(range2);
let ipset = builder.build();
assert!(!ipset.is_empty());
assert_eq!(ipset.len(), 1);
assert_eq!(
ipset.ranges()[0].start(),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)
);
assert_eq!(
ipset.ranges()[0].end(),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20)
);
}
#[test]
fn test_v6_ipset_multi_add_disjoint_ranges() {
let start1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
let end1 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10);
let range1 = IpRange::new(start1, end1);
let start2 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 12);
let end2 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20);
let range2 = IpRange::new(start2, end2);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(range1);
builder.add_range(range2);
let ipset = builder.build();
assert!(!ipset.is_empty());
assert_eq!(ipset.len(), 2);
assert_eq!(
ipset.ranges()[0].start(),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)
);
assert_eq!(
ipset.ranges()[0].end(),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10)
);
assert_eq!(
ipset.ranges()[1].start(),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 12)
);
assert_eq!(
ipset.ranges()[1].end(),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20)
);
}
#[test]
fn test_add_ip() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_ip(Ipv4Addr::new(192, 168, 1, 1));
let ipset = builder.build();
assert!(!ipset.is_empty());
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv4Addr::new(192, 168, 1, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv4Addr::new(192, 168, 1, 1));
}
#[test]
fn test_v6_add_ip() {
let ip = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_ip(ip);
let ipset = builder.build();
assert!(!ipset.is_empty());
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), ip);
assert_eq!(ipset.ranges()[0].end(), ip);
}
#[test]
fn test_remove_ip() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_ip(Ipv4Addr::new(192, 168, 1, 1));
builder.remove_ip(Ipv4Addr::new(192, 168, 1, 1));
let ipset = builder.build();
assert!(ipset.is_empty());
assert_eq!(ipset.len(), 0);
}
#[test]
fn test_v6_remove_ip() {
let ip = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_ip(ip);
builder.remove_ip(ip);
let ipset = builder.build();
assert!(ipset.is_empty());
}
#[test]
fn test_remove_ip_splits_range() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 1),
Ipv4Addr::new(10, 0, 0, 10),
));
builder.remove_ip(Ipv4Addr::new(10, 0, 0, 5));
let ipset = builder.build();
assert_eq!(ipset.len(), 2);
assert_eq!(ipset.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 4));
assert_eq!(ipset.ranges()[1].start(), Ipv4Addr::new(10, 0, 0, 6));
assert_eq!(ipset.ranges()[1].end(), Ipv4Addr::new(10, 0, 0, 10));
}
#[test]
fn test_v6_remove_ip_splits_range() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.remove_ip(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 5));
let ipset = builder.build();
assert_eq!(ipset.len(), 2);
assert_eq!(ipset.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 4));
assert_eq!(ipset.ranges()[1].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 6));
assert_eq!(ipset.ranges()[1].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10));
}
#[test]
fn test_remove_ip_not_in_set() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 1),
Ipv4Addr::new(10, 0, 0, 10),
));
builder.remove_ip(Ipv4Addr::new(10, 0, 0, 20));
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
}
#[test]
fn test_v6_remove_ip_not_in_set() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.remove_ip(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20));
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
}
#[test]
fn test_add_ip_merges_adjacent() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 1),
Ipv4Addr::new(10, 0, 0, 10),
));
builder.add_ip(Ipv4Addr::new(10, 0, 0, 11));
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 11));
}
#[test]
fn test_v6_add_ip_merges_adjacent() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.add_ip(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 11));
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 11));
}
#[test]
fn test_remove_range_invalid_is_noop() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 1),
Ipv4Addr::new(10, 0, 0, 10),
));
builder.remove_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 10),
Ipv4Addr::new(10, 0, 0, 1), ));
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 10));
}
#[test]
fn test_v6_remove_range_invalid_is_noop() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.remove_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), ));
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10));
}
#[test]
fn test_remove_range() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(192, 168, 1, 1),
Ipv4Addr::new(192, 168, 1, 255),
));
builder.remove_range(IpRange::new(
Ipv4Addr::new(192, 168, 1, 1),
Ipv4Addr::new(192, 168, 1, 255),
));
let ipset = builder.build();
assert!(ipset.is_empty());
assert_eq!(ipset.len(), 0);
}
#[test]
fn test_remove_range_no_overlap() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 1),
Ipv4Addr::new(10, 0, 0, 10),
));
builder.remove_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 20),
Ipv4Addr::new(10, 0, 0, 30),
));
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 10));
}
#[test]
fn test_remove_range_clips_left_of_stored() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 1),
Ipv4Addr::new(10, 0, 0, 10),
));
builder.remove_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 1),
Ipv4Addr::new(10, 0, 0, 5),
));
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 6));
assert_eq!(ipset.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 10));
}
#[test]
fn test_remove_range_clips_right_of_stored() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 1),
Ipv4Addr::new(10, 0, 0, 10),
));
builder.remove_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 6),
Ipv4Addr::new(10, 0, 0, 10),
));
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 5));
}
#[test]
fn test_remove_range_middle_split() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 1),
Ipv4Addr::new(10, 0, 0, 10),
));
builder.remove_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 4),
Ipv4Addr::new(10, 0, 0, 7),
));
let ipset = builder.build();
assert_eq!(ipset.len(), 2);
assert_eq!(ipset.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 3));
assert_eq!(ipset.ranges()[1].start(), Ipv4Addr::new(10, 0, 0, 8));
assert_eq!(ipset.ranges()[1].end(), Ipv4Addr::new(10, 0, 0, 10));
}
#[test]
fn test_v6_remove_range() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.remove_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
assert!(builder.build().is_empty());
}
#[test]
fn test_v6_remove_range_no_overlap() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.remove_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 30),
));
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10));
}
#[test]
fn test_v6_remove_range_clips_left_of_stored() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.remove_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 5),
));
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 6));
assert_eq!(ipset.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10));
}
#[test]
fn test_v6_remove_range_clips_right_of_stored() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.remove_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 6),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 5));
}
#[test]
fn test_v6_remove_range_middle_split() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.remove_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 4),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 7),
));
let ipset = builder.build();
assert_eq!(ipset.len(), 2);
assert_eq!(ipset.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 3));
assert_eq!(ipset.ranges()[1].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 8));
assert_eq!(ipset.ranges()[1].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10));
}
#[test]
fn test_remove_prefix() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_prefix(IpPrefix::new(Ipv4Addr::new(192, 168, 1, 0), 24).unwrap());
builder.remove_prefix(IpPrefix::new(Ipv4Addr::new(192, 168, 1, 0), 24).unwrap());
let ipset = builder.build();
assert!(ipset.is_empty());
assert_eq!(ipset.len(), 0);
}
#[test]
fn test_v6_remove_prefix() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_prefix(IpPrefix::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0), 32).unwrap());
builder.remove_prefix(IpPrefix::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0), 32).unwrap());
assert!(builder.build().is_empty());
}
#[test]
fn test_v4_builder_empty() {
let ipset = IpSetBuilder::<Ipv4Addr>::new().build();
assert!(ipset.is_empty());
assert_eq!(ipset.len(), 0);
}
#[test]
fn test_v6_builder_empty() {
let ipset = IpSetBuilder::<Ipv6Addr>::new().build();
assert!(ipset.is_empty());
assert_eq!(ipset.len(), 0);
}
#[test]
fn test_v4_builder_invalid_range_ignored() {
let invalid = IpRange::new(Ipv4Addr::new(10, 0, 0, 10), Ipv4Addr::new(10, 0, 0, 0));
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(invalid);
assert!(builder.build().is_empty());
}
#[test]
fn test_v6_builder_invalid_range_ignored() {
let invalid = IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(invalid);
assert!(builder.build().is_empty());
}
#[test]
fn test_v4_builder_add_prefix() {
let prefix = IpPrefix::new(Ipv4Addr::new(10, 0, 0, 0), 8).unwrap();
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_prefix(prefix);
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 0));
assert_eq!(ipset.ranges()[0].end(), Ipv4Addr::new(10, 255, 255, 255));
}
#[test]
fn test_v6_builder_add_prefix() {
let prefix = IpPrefix::new(Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 0), 120).unwrap();
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_prefix(prefix);
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(
ipset.ranges()[0].start(),
Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 0)
);
assert_eq!(
ipset.ranges()[0].end(),
Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 255)
);
}
#[test]
fn test_v6_builder_overlapping_ranges_merged() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 30),
));
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(ipset.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 30));
}
#[test]
fn test_v4_builder_overlapping_ranges_merged() {
let range1 = IpRange::new(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 10));
let range2 = IpRange::new(Ipv4Addr::new(10, 0, 0, 5), Ipv4Addr::new(10, 0, 0, 20));
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(range1);
builder.add_range(range2);
let ipset = builder.build();
assert_eq!(ipset.len(), 1);
assert_eq!(ipset.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 0));
assert_eq!(ipset.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 20));
}
#[test]
fn test_v6_builder_three_ranges_partial_merge() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 5),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 60),
));
let ipset = builder.build();
assert_eq!(ipset.len(), 2);
assert_eq!(ipset.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(ipset.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20));
assert_eq!(ipset.ranges()[1].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50));
assert_eq!(ipset.ranges()[1].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 60));
}
#[test]
fn test_v4_builder_three_ranges_partial_merge() {
let range1 = IpRange::new(Ipv4Addr::new(10, 0, 0, 1), Ipv4Addr::new(10, 0, 0, 5));
let range2 = IpRange::new(Ipv4Addr::new(10, 0, 0, 3), Ipv4Addr::new(10, 0, 0, 8));
let range3 = IpRange::new(Ipv4Addr::new(10, 0, 0, 20), Ipv4Addr::new(10, 0, 0, 30));
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(range1);
builder.add_range(range2);
builder.add_range(range3);
let ipset = builder.build();
assert_eq!(ipset.len(), 2);
assert_eq!(ipset.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 1));
assert_eq!(ipset.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 8));
assert_eq!(ipset.ranges()[1].start(), Ipv4Addr::new(10, 0, 0, 20));
assert_eq!(ipset.ranges()[1].end(), Ipv4Addr::new(10, 0, 0, 30));
}
#[test]
fn test_v6_contains_ip_start_boundary() {
let mut b = IpSetBuilder::<Ipv6Addr>::new();
b.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
let set = b.build();
assert!(set.contains_ip(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10))); assert!(!set.contains_ip(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 9))); }
#[test]
fn test_v6_contains_ip_end_boundary() {
let mut b = IpSetBuilder::<Ipv6Addr>::new();
b.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
let set = b.build();
assert!(set.contains_ip(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20))); assert!(!set.contains_ip(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 21))); }
#[test]
fn test_v6_contains_ip_empty_set() {
let empty = IpSetBuilder::<Ipv6Addr>::new().build();
assert!(!empty.contains_ip(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)));
}
#[test]
fn test_v4_contains_ip_start_boundary() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 1),
Ipv4Addr::new(10, 0, 0, 10),
));
let ipset = builder.build();
assert!(ipset.contains_ip(Ipv4Addr::new(10, 0, 0, 1))); assert!(!ipset.contains_ip(Ipv4Addr::new(10, 0, 0, 0))); }
#[test]
fn test_v4_contains_ip_end_boundary() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 1),
Ipv4Addr::new(10, 0, 0, 10),
));
let ipset = builder.build();
assert!(ipset.contains_ip(Ipv4Addr::new(10, 0, 0, 10))); assert!(!ipset.contains_ip(Ipv4Addr::new(10, 0, 0, 11))); }
#[test]
fn test_v4_contains_ip_in_gap() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 1),
Ipv4Addr::new(10, 0, 0, 5),
));
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 10),
Ipv4Addr::new(10, 0, 0, 20),
));
let ipset = builder.build();
assert!(!ipset.contains_ip(Ipv4Addr::new(10, 0, 0, 7))); assert!(ipset.contains_ip(Ipv4Addr::new(10, 0, 0, 5))); assert!(ipset.contains_ip(Ipv4Addr::new(10, 0, 0, 10))); }
#[test]
fn test_v6_contains_ip_in_gap() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 5),
));
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
let ipset = builder.build();
assert!(!ipset.contains_ip(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 7)));
}
#[test]
fn test_v4_contains_ip_empty_set() {
let ipset = IpSetBuilder::<Ipv4Addr>::new().build();
assert!(!ipset.contains_ip(Ipv4Addr::new(10, 0, 0, 1)));
}
#[test]
fn test_v4_contains_range_fully_contained() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 100),
));
let ipset = builder.build();
let query = IpRange::new(Ipv4Addr::new(10, 0, 0, 10), Ipv4Addr::new(10, 0, 0, 50));
assert!(ipset.contains_range(query));
}
#[test]
fn test_v6_contains_range_exact_match() {
let range = IpRange::new(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0xff),
);
let mut b = IpSetBuilder::<Ipv6Addr>::new();
b.add_range(range);
let set = b.build();
assert!(set.contains_range(range));
}
#[test]
fn test_v6_contains_range_exceeds_stored() {
let mut b = IpSetBuilder::<Ipv6Addr>::new();
b.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
let set = b.build();
let wide = IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 5),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 25),
);
assert!(!set.contains_range(wide));
}
#[test]
fn test_v6_contains_range_invalid_input() {
let mut b = IpSetBuilder::<Ipv6Addr>::new();
b.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
let set = b.build();
let bad = IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 5),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 3),
);
assert!(!set.contains_range(bad));
}
#[test]
fn test_v4_contains_range_exact_match() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 100),
));
let ipset = builder.build();
let query = IpRange::new(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 100));
assert!(ipset.contains_range(query));
}
#[test]
fn test_v4_contains_range_spans_gap() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 10),
));
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 20),
Ipv4Addr::new(10, 0, 0, 30),
));
let ipset = builder.build();
let query = IpRange::new(Ipv4Addr::new(10, 0, 0, 5), Ipv4Addr::new(10, 0, 0, 25));
assert!(!ipset.contains_range(query));
}
#[test]
fn test_v4_contains_range_exceeds_stored() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 10),
Ipv4Addr::new(10, 0, 0, 20),
));
let ipset = builder.build();
let query = IpRange::new(Ipv4Addr::new(10, 0, 0, 5), Ipv4Addr::new(10, 0, 0, 25));
assert!(!ipset.contains_range(query));
}
#[test]
fn test_v4_contains_range_invalid_input() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 100),
));
let ipset = builder.build();
let invalid = IpRange::new(Ipv4Addr::new(10, 0, 0, 50), Ipv4Addr::new(10, 0, 0, 10));
assert!(!ipset.contains_range(invalid));
}
#[test]
fn test_v6_contains_range_fully_contained() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 100),
));
let ipset = builder.build();
let query = IpRange::new(
Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(1, 0, 0, 0, 0, 0, 0, 50),
);
assert!(ipset.contains_range(query));
}
#[test]
fn test_v6_contains_range_spans_gap() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 30),
));
let ipset = builder.build();
let query = IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 5),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 25),
);
assert!(!ipset.contains_range(query));
}
#[test]
fn test_v4_overlaps_ip_set_overlap() {
let mut b1 = IpSetBuilder::<Ipv4Addr>::new();
b1.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 20),
));
let set1 = b1.build();
let mut b2 = IpSetBuilder::<Ipv4Addr>::new();
b2.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 10),
Ipv4Addr::new(10, 0, 0, 30),
));
let set2 = b2.build();
assert!(set1.overlaps_ip_set(&set2));
assert!(set2.overlaps_ip_set(&set1)); }
#[test]
fn test_v4_overlaps_ip_set_disjoint() {
let mut b1 = IpSetBuilder::<Ipv4Addr>::new();
b1.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 10),
));
let set1 = b1.build();
let mut b2 = IpSetBuilder::<Ipv4Addr>::new();
b2.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 20),
Ipv4Addr::new(10, 0, 0, 30),
));
let set2 = b2.build();
assert!(!set1.overlaps_ip_set(&set2));
assert!(!set2.overlaps_ip_set(&set1)); }
#[test]
fn test_v4_overlaps_ip_set_empty() {
let mut b1 = IpSetBuilder::<Ipv4Addr>::new();
b1.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 10),
));
let populated = b1.build();
let empty = IpSetBuilder::<Ipv4Addr>::new().build();
assert!(!populated.overlaps_ip_set(&empty));
assert!(!empty.overlaps_ip_set(&populated));
assert!(!empty.overlaps_ip_set(&empty));
}
#[test]
fn test_v6_overlaps_ip_set_single_address_touch() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
assert!(a.overlaps_ip_set(&b));
assert!(b.overlaps_ip_set(&a));
}
#[test]
fn test_v6_overlaps_ip_set_subset() {
let outer = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 100),
);
let inner = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
assert!(outer.overlaps_ip_set(&inner));
assert!(inner.overlaps_ip_set(&outer));
}
#[test]
fn test_v4_overlaps_ip_set_single_address_touch() {
let mut b1 = IpSetBuilder::<Ipv4Addr>::new();
b1.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 10),
));
let set1 = b1.build();
let mut b2 = IpSetBuilder::<Ipv4Addr>::new();
b2.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 10),
Ipv4Addr::new(10, 0, 0, 20),
));
let set2 = b2.build();
assert!(set1.overlaps_ip_set(&set2));
}
#[test]
fn test_v4_overlaps_ip_set_subset() {
let mut b1 = IpSetBuilder::<Ipv4Addr>::new();
b1.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 100),
));
let outer = b1.build();
let mut b2 = IpSetBuilder::<Ipv4Addr>::new();
b2.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 40),
Ipv4Addr::new(10, 0, 0, 60),
));
let inner = b2.build();
assert!(outer.overlaps_ip_set(&inner));
assert!(inner.overlaps_ip_set(&outer)); }
#[test]
fn test_v6_overlaps_ip_set_overlap() {
let mut b1 = IpSetBuilder::<Ipv6Addr>::new();
b1.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
let set1 = b1.build();
let mut b2 = IpSetBuilder::<Ipv6Addr>::new();
b2.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 30),
));
let set2 = b2.build();
assert!(set1.overlaps_ip_set(&set2));
assert!(set2.overlaps_ip_set(&set1)); }
#[test]
fn test_v6_overlaps_ip_set_disjoint() {
let mut b1 = IpSetBuilder::<Ipv6Addr>::new();
b1.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
let set1 = b1.build();
let mut b2 = IpSetBuilder::<Ipv6Addr>::new();
b2.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 30),
));
let set2 = b2.build();
assert!(!set1.overlaps_ip_set(&set2));
assert!(!set2.overlaps_ip_set(&set1)); }
#[test]
fn test_v6_overlaps_ip_set_empty() {
let mut b1 = IpSetBuilder::<Ipv6Addr>::new();
b1.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
let populated = b1.build();
let empty = IpSetBuilder::<Ipv6Addr>::new().build();
assert!(!populated.overlaps_ip_set(&empty));
assert!(!empty.overlaps_ip_set(&populated));
}
#[test]
fn test_v4_ipset_prefixes_single_range() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(192, 168, 1, 0),
Ipv4Addr::new(192, 168, 1, 255),
));
let ipset = builder.build();
let prefixes = ipset.prefixes();
assert_eq!(prefixes.len(), 1);
assert_eq!(prefixes[0].ip(), Ipv4Addr::new(192, 168, 1, 0));
assert_eq!(prefixes[0].mask(), 24);
}
#[test]
fn test_v6_ipset_prefixes_single_range() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 255),
));
let ipset = builder.build();
let prefixes = ipset.prefixes();
assert_eq!(prefixes.len(), 1);
assert_eq!(prefixes[0].ip(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(prefixes[0].mask(), 120);
}
#[test]
fn test_v4_ipset_prefixes_multiple_ranges() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 255),
));
builder.add_range(IpRange::new(
Ipv4Addr::new(192, 168, 1, 0),
Ipv4Addr::new(192, 168, 1, 255),
));
let ipset = builder.build();
let prefixes = ipset.prefixes();
assert_eq!(prefixes.len(), 2);
assert_eq!(prefixes[0].ip(), Ipv4Addr::new(10, 0, 0, 0));
assert_eq!(prefixes[0].mask(), 24);
assert_eq!(prefixes[1].ip(), Ipv4Addr::new(192, 168, 1, 0));
assert_eq!(prefixes[1].mask(), 24);
}
#[test]
fn test_v6_ipset_prefixes_multiple_ranges() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 255),
));
builder.add_range(IpRange::new(
Ipv6Addr::new(2001, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(2001, 0, 0, 0, 0, 0, 0, 255),
));
let ipset = builder.build();
let prefixes = ipset.prefixes();
assert_eq!(prefixes.len(), 2);
assert_eq!(prefixes[0].ip(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(prefixes[0].mask(), 120);
assert_eq!(prefixes[1].ip(), Ipv6Addr::new(2001, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(prefixes[1].mask(), 120);
}
#[test]
fn test_v4_ipset_prefixes_empty_set() {
let ipset = IpSetBuilder::<Ipv4Addr>::new().build();
assert!(ipset.prefixes().is_empty());
}
#[test]
fn test_v6_ipset_prefixes_empty_set() {
let ipset = IpSetBuilder::<Ipv6Addr>::new().build();
assert!(ipset.prefixes().is_empty());
}
#[test]
fn test_v4_ipset_contains_ip() {
let start = Ipv4Addr::new(192, 168, 0, 0);
let end = Ipv4Addr::new(192, 168, 255, 255);
let range = IpRange::new(start, end);
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(range);
let ipset = builder.build();
assert!(ipset.contains_ip(Ipv4Addr::new(192, 168, 1, 1)));
}
#[test]
fn test_v6_ipset_contains_ip() {
let start = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
let end = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10);
let range = IpRange::new(start, end);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(range);
let ipset = builder.build();
assert!(ipset.contains_ip(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)));
}
#[test]
fn test_v4_ipset_not_contains_ip() {
let start = Ipv4Addr::new(192, 168, 0, 0);
let end = Ipv4Addr::new(192, 168, 255, 255);
let range = IpRange::new(start, end);
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(range);
let ipset = builder.build();
assert!(!ipset.contains_ip(Ipv4Addr::new(192, 169, 0, 0)));
}
#[test]
fn test_v6_ipset_not_contains_ip() {
let start = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
let end = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10);
let range = IpRange::new(start, end);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(range);
let ipset = builder.build();
assert!(!ipset.contains_ip(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 11)));
}
fn make_v4_set(start: Ipv4Addr, end: Ipv4Addr) -> super::IpSet<Ipv4Addr> {
let mut b = IpSetBuilder::new();
b.add_range(IpRange::new(start, end));
b.build()
}
fn make_v6_set(start: Ipv6Addr, end: Ipv6Addr) -> super::IpSet<Ipv6Addr> {
let mut b = IpSetBuilder::new();
b.add_range(IpRange::new(start, end));
b.build()
}
#[test]
fn test_v4_union_disjoint() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let b = make_v4_set(
Ipv4Addr::new(192, 168, 1, 0),
Ipv4Addr::new(192, 168, 1, 255),
);
let u = a.union(&b);
assert_eq!(u.len(), 2);
assert!(u.contains_ip(Ipv4Addr::new(10, 0, 0, 1)));
assert!(u.contains_ip(Ipv4Addr::new(192, 168, 1, 1)));
assert!(!u.contains_ip(Ipv4Addr::new(172, 16, 0, 1)));
}
#[test]
fn test_v4_union_overlapping() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 10));
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 5), Ipv4Addr::new(10, 0, 0, 20));
let u = a.union(&b);
assert_eq!(u.len(), 1);
assert_eq!(u.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 0));
assert_eq!(u.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 20));
}
#[test]
fn test_v4_union_adjacent() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 127));
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 128), Ipv4Addr::new(10, 0, 0, 255));
let u = a.union(&b);
assert_eq!(u.len(), 1);
assert_eq!(u.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 0));
assert_eq!(u.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 255));
}
#[test]
fn test_v4_union_subset() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 50), Ipv4Addr::new(10, 0, 0, 100));
let u = a.union(&b);
assert_eq!(u.len(), 1);
assert_eq!(u.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 0));
assert_eq!(u.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 255));
}
#[test]
fn test_v4_union_with_empty() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let empty = IpSetBuilder::<Ipv4Addr>::new().build();
assert_eq!(a.union(&empty), a);
assert_eq!(empty.union(&a), a);
}
#[test]
fn test_v4_union_both_empty() {
let a = IpSetBuilder::<Ipv4Addr>::new().build();
let b = IpSetBuilder::<Ipv4Addr>::new().build();
assert!(a.union(&b).is_empty());
}
#[test]
fn test_v4_union_symmetric() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let b = make_v4_set(
Ipv4Addr::new(192, 168, 1, 0),
Ipv4Addr::new(192, 168, 1, 255),
);
assert_eq!(a.union(&b), b.union(&a));
}
#[test]
fn test_v6_union_adjacent() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 11),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
let u = a.union(&b);
assert_eq!(u.len(), 1);
assert_eq!(u.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(u.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20));
}
#[test]
fn test_v6_union_subset() {
let outer = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 100),
);
let inner = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
assert_eq!(outer.union(&inner), outer);
}
#[test]
fn test_v6_union_with_empty() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
);
let empty = IpSetBuilder::<Ipv6Addr>::new().build();
assert_eq!(a.union(&empty), a);
assert_eq!(empty.union(&a), a);
}
#[test]
fn test_v6_union_both_empty() {
let empty = IpSetBuilder::<Ipv6Addr>::new().build();
assert!(empty.union(&empty).is_empty());
}
#[test]
fn test_v6_union_symmetric() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 5),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
assert_eq!(a.union(&b), b.union(&a));
}
#[test]
fn test_v6_union_disjoint() {
let a = make_v6_set(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0xff),
);
let b = make_v6_set(
Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 0xff),
);
let u = a.union(&b);
assert_eq!(u.len(), 2);
assert!(u.contains_ip(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)));
assert!(u.contains_ip(Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 1)));
}
#[test]
fn test_v6_union_overlapping() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 5),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
let u = a.union(&b);
assert_eq!(u.len(), 1);
assert_eq!(u.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(u.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20));
}
#[test]
fn test_v4_difference_clips_left() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 100));
let d = a.difference(&b);
assert_eq!(d.len(), 1);
assert_eq!(d.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 101));
assert_eq!(d.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 255));
}
#[test]
fn test_v4_difference_clips_right() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 100), Ipv4Addr::new(10, 0, 0, 255));
let d = a.difference(&b);
assert_eq!(d.len(), 1);
assert_eq!(d.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 0));
assert_eq!(d.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 99));
}
#[test]
fn test_v4_difference_punches_hole() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 50), Ipv4Addr::new(10, 0, 0, 100));
let d = a.difference(&b);
assert_eq!(d.len(), 2);
assert_eq!(d.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 0));
assert_eq!(d.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 49));
assert_eq!(d.ranges()[1].start(), Ipv4Addr::new(10, 0, 0, 101));
assert_eq!(d.ranges()[1].end(), Ipv4Addr::new(10, 0, 0, 255));
}
#[test]
fn test_v4_difference_disjoint() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let b = make_v4_set(
Ipv4Addr::new(192, 168, 1, 0),
Ipv4Addr::new(192, 168, 1, 255),
);
let d = a.difference(&b);
assert_eq!(d, a);
}
#[test]
fn test_v4_difference_equal() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
assert!(a.difference(&a).is_empty());
}
#[test]
fn test_v4_difference_fully_covered() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 50), Ipv4Addr::new(10, 0, 0, 100));
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
assert!(a.difference(&b).is_empty());
}
#[test]
fn test_v4_difference_with_empty() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let empty = IpSetBuilder::<Ipv4Addr>::new().build();
assert_eq!(a.difference(&empty), a);
assert!(empty.difference(&a).is_empty());
}
#[test]
fn test_v4_difference_not_symmetric() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 100), Ipv4Addr::new(10, 0, 1, 255));
assert_ne!(a.difference(&b), b.difference(&a));
}
#[test]
fn test_v4_difference_multi_range() {
let mut ba = IpSetBuilder::<Ipv4Addr>::new();
ba.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 255),
));
ba.add_range(IpRange::new(
Ipv4Addr::new(192, 168, 1, 0),
Ipv4Addr::new(192, 168, 1, 255),
));
let a = ba.build();
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let d = a.difference(&b);
assert_eq!(d.len(), 1);
assert_eq!(d.ranges()[0].start(), Ipv4Addr::new(192, 168, 1, 0));
assert_eq!(d.ranges()[0].end(), Ipv4Addr::new(192, 168, 1, 255));
}
#[test]
fn test_v6_difference_clips_left() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
);
let d = a.difference(&b);
assert_eq!(d.len(), 1);
assert_eq!(d.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 11));
assert_eq!(d.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20));
}
#[test]
fn test_v6_difference_clips_right() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
let d = a.difference(&b);
assert_eq!(d.len(), 1);
assert_eq!(d.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(d.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 9));
}
#[test]
fn test_v6_difference_equal() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
assert!(a.difference(&a).is_empty());
}
#[test]
fn test_v6_difference_fully_covered() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 5),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 15),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
assert!(a.difference(&b).is_empty());
}
#[test]
fn test_v6_difference_with_empty() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
let empty = IpSetBuilder::<Ipv6Addr>::new().build();
assert_eq!(a.difference(&empty), a);
assert!(empty.difference(&a).is_empty());
}
#[test]
fn test_v6_difference_not_symmetric() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 30),
);
assert_ne!(a.difference(&b), b.difference(&a));
}
#[test]
fn test_v6_difference_multi_range() {
let mut ba = IpSetBuilder::<Ipv6Addr>::new();
ba.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 100),
));
let a = ba.build();
let mut bb = IpSetBuilder::<Ipv6Addr>::new();
bb.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
bb.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 60),
));
let b = bb.build();
let d = a.difference(&b);
assert_eq!(d.len(), 3);
assert_eq!(d.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(d.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 9));
assert_eq!(d.ranges()[1].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 21));
assert_eq!(d.ranges()[1].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 49));
assert_eq!(d.ranges()[2].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 61));
assert_eq!(d.ranges()[2].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 100));
}
#[test]
fn test_v6_difference_punches_hole() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 255),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 100),
);
let d = a.difference(&b);
assert_eq!(d.len(), 2);
assert_eq!(d.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(d.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 49));
assert_eq!(
d.ranges()[1].start(),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 101)
);
assert_eq!(d.ranges()[1].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 255));
}
#[test]
fn test_v6_difference_disjoint() {
let a = make_v6_set(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0xff),
);
let b = make_v6_set(
Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 0xff),
);
assert_eq!(a.difference(&b), a);
}
#[test]
fn test_v4_intersection_subset() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 50), Ipv4Addr::new(10, 0, 0, 100));
assert_eq!(a.intersection(&b), b);
}
#[test]
fn test_v4_intersection_partial_overlap() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 150));
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 100), Ipv4Addr::new(10, 0, 0, 255));
let inter = a.intersection(&b);
assert_eq!(inter.len(), 1);
assert_eq!(inter.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 100));
assert_eq!(inter.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 150));
}
#[test]
fn test_v4_intersection_disjoint() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let b = make_v4_set(
Ipv4Addr::new(192, 168, 1, 0),
Ipv4Addr::new(192, 168, 1, 255),
);
assert!(a.intersection(&b).is_empty());
}
#[test]
fn test_v4_intersection_equal() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
assert_eq!(a.intersection(&a), a);
}
#[test]
fn test_v4_intersection_with_empty() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let empty = IpSetBuilder::<Ipv4Addr>::new().build();
assert!(a.intersection(&empty).is_empty());
assert!(empty.intersection(&a).is_empty());
}
#[test]
fn test_v4_intersection_symmetric() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 200));
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 100), Ipv4Addr::new(10, 0, 0, 255));
assert_eq!(a.intersection(&b), b.intersection(&a));
}
#[test]
fn test_v4_intersection_multiple_ranges() {
let mut ba = IpSetBuilder::<Ipv4Addr>::new();
ba.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 100),
));
ba.add_range(IpRange::new(
Ipv4Addr::new(192, 168, 0, 0),
Ipv4Addr::new(192, 168, 0, 255),
));
let a = ba.build();
let mut bb = IpSetBuilder::<Ipv4Addr>::new();
bb.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 50),
Ipv4Addr::new(10, 0, 0, 200),
));
bb.add_range(IpRange::new(
Ipv4Addr::new(192, 168, 0, 100),
Ipv4Addr::new(192, 168, 1, 50),
));
let b = bb.build();
let inter = a.intersection(&b);
assert_eq!(inter.len(), 2);
assert_eq!(inter.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 50));
assert_eq!(inter.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 100));
assert_eq!(inter.ranges()[1].start(), Ipv4Addr::new(192, 168, 0, 100));
assert_eq!(inter.ranges()[1].end(), Ipv4Addr::new(192, 168, 0, 255));
}
#[test]
fn test_v4_intersection_tied_ends() {
let mut ba = IpSetBuilder::<Ipv4Addr>::new();
ba.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 255),
));
ba.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 1, 0),
Ipv4Addr::new(10, 0, 1, 255),
));
let a = ba.build();
let mut bb = IpSetBuilder::<Ipv4Addr>::new();
bb.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 100),
Ipv4Addr::new(10, 0, 0, 255),
));
bb.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 1, 100),
Ipv4Addr::new(10, 0, 1, 255),
));
let b = bb.build();
let inter = a.intersection(&b);
assert_eq!(inter.len(), 2);
assert_eq!(inter.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 100));
assert_eq!(inter.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 255));
assert_eq!(inter.ranges()[1].start(), Ipv4Addr::new(10, 0, 1, 100));
assert_eq!(inter.ranges()[1].end(), Ipv4Addr::new(10, 0, 1, 255));
}
#[test]
fn test_v6_intersection_partial_overlap() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 15),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 25),
);
let i = a.intersection(&b);
assert_eq!(i.len(), 1);
assert_eq!(i.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10));
assert_eq!(i.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 15));
}
#[test]
fn test_v6_intersection_equal() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
assert_eq!(a.intersection(&a), a);
}
#[test]
fn test_v6_intersection_with_empty() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
let empty = IpSetBuilder::<Ipv6Addr>::new().build();
assert!(a.intersection(&empty).is_empty());
assert!(empty.intersection(&a).is_empty());
}
#[test]
fn test_v6_intersection_symmetric() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 15),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 25),
);
assert_eq!(a.intersection(&b), b.intersection(&a));
}
#[test]
fn test_v6_intersection_multiple_ranges() {
let mut ba = IpSetBuilder::<Ipv6Addr>::new();
ba.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
ba.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 70),
));
let a = ba.build();
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 60),
);
let i = a.intersection(&b);
assert_eq!(i.len(), 2);
assert_eq!(i.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10));
assert_eq!(i.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20));
assert_eq!(i.ranges()[1].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50));
assert_eq!(i.ranges()[1].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 60));
}
#[test]
fn test_v6_intersection_tied_ends() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
let i = a.intersection(&b);
assert_eq!(i.len(), 1);
assert_eq!(i.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10));
assert_eq!(i.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10));
}
#[test]
fn test_v6_intersection_subset() {
let a = make_v6_set(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0xff),
);
let b = make_v6_set(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0x40),
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0x80),
);
assert_eq!(a.intersection(&b), b);
}
#[test]
fn test_v6_intersection_disjoint() {
let a = make_v6_set(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0xff),
);
let b = make_v6_set(
Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 0xff),
);
assert!(a.intersection(&b).is_empty());
}
#[test]
fn test_v4_complement_empty() {
let empty = IpSetBuilder::<Ipv4Addr>::new().build();
let c = empty.complement();
assert_eq!(c.len(), 1);
assert_eq!(c.ranges()[0].start(), Ipv4Addr::new(0, 0, 0, 0));
assert_eq!(c.ranges()[0].end(), Ipv4Addr::new(255, 255, 255, 255));
}
#[test]
fn test_v4_complement_full_space() {
let mut b = IpSetBuilder::<Ipv4Addr>::new();
b.add_range(IpRange::new(
Ipv4Addr::new(0, 0, 0, 0),
Ipv4Addr::new(255, 255, 255, 255),
));
let full = b.build();
assert!(full.complement().is_empty());
}
#[test]
fn test_v4_complement_middle_range() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let c = a.complement();
assert_eq!(c.len(), 2);
assert_eq!(c.ranges()[0].start(), Ipv4Addr::new(0, 0, 0, 0));
assert_eq!(c.ranges()[0].end(), Ipv4Addr::new(9, 255, 255, 255));
assert_eq!(c.ranges()[1].start(), Ipv4Addr::new(10, 0, 1, 0));
assert_eq!(c.ranges()[1].end(), Ipv4Addr::new(255, 255, 255, 255));
}
#[test]
fn test_v4_complement_starts_at_zero() {
let a = make_v4_set(Ipv4Addr::new(0, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let c = a.complement();
assert_eq!(c.len(), 1);
assert_eq!(c.ranges()[0].start(), Ipv4Addr::new(10, 0, 1, 0));
assert_eq!(c.ranges()[0].end(), Ipv4Addr::new(255, 255, 255, 255));
}
#[test]
fn test_v4_complement_ends_at_max() {
let a = make_v4_set(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(255, 255, 255, 255),
);
let c = a.complement();
assert_eq!(c.len(), 1);
assert_eq!(c.ranges()[0].start(), Ipv4Addr::new(0, 0, 0, 0));
assert_eq!(c.ranges()[0].end(), Ipv4Addr::new(9, 255, 255, 255));
}
#[test]
fn test_v4_complement_double() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
assert_eq!(a.complement().complement(), a);
}
#[test]
fn test_v4_complement_multiple_ranges() {
let mut ba = IpSetBuilder::<Ipv4Addr>::new();
ba.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 255),
));
ba.add_range(IpRange::new(
Ipv4Addr::new(192, 168, 0, 0),
Ipv4Addr::new(192, 168, 0, 255),
));
let a = ba.build();
let c = a.complement();
assert_eq!(c.len(), 3);
assert_eq!(c.ranges()[0].start(), Ipv4Addr::new(0, 0, 0, 0));
assert_eq!(c.ranges()[0].end(), Ipv4Addr::new(9, 255, 255, 255));
assert_eq!(c.ranges()[1].start(), Ipv4Addr::new(10, 0, 1, 0));
assert_eq!(c.ranges()[1].end(), Ipv4Addr::new(192, 167, 255, 255));
assert_eq!(c.ranges()[2].start(), Ipv4Addr::new(192, 168, 1, 0));
assert_eq!(c.ranges()[2].end(), Ipv4Addr::new(255, 255, 255, 255));
}
#[test]
fn test_v4_complement_union_is_full() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let c = a.complement();
let full = a.union(&c);
assert_eq!(full.len(), 1);
assert_eq!(full.ranges()[0].start(), Ipv4Addr::new(0, 0, 0, 0));
assert_eq!(full.ranges()[0].end(), Ipv4Addr::new(255, 255, 255, 255));
}
#[test]
fn test_v4_complement_intersection_is_empty() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
assert!(a.intersection(&a.complement()).is_empty());
}
#[test]
fn test_v6_complement_full_space() {
let mut b = IpSetBuilder::<Ipv6Addr>::new();
b.add_range(IpRange::new(
Ipv6Addr::from(0u128),
Ipv6Addr::from(u128::MAX),
));
assert!(b.build().complement().is_empty());
}
#[test]
fn test_v6_complement_starts_at_zero() {
let a = make_v6_set(Ipv6Addr::from(0u128), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0xff));
let c = a.complement();
assert_eq!(c.len(), 1);
assert_eq!(c.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x100));
assert_eq!(c.ranges()[0].end(), Ipv6Addr::from(u128::MAX));
}
#[test]
fn test_v6_complement_ends_at_max() {
let a = make_v6_set(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
Ipv6Addr::from(u128::MAX),
);
let c = a.complement();
assert_eq!(c.len(), 1);
assert_eq!(c.ranges()[0].start(), Ipv6Addr::from(0u128));
assert_eq!(
c.ranges()[0].end(),
Ipv6Addr::from(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).to_bits() - 1
)
);
}
#[test]
fn test_v6_complement_multiple_ranges() {
let mut ba = IpSetBuilder::<Ipv6Addr>::new();
ba.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
ba.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 60),
));
let a = ba.build();
let c = a.complement();
assert_eq!(c.len(), 3);
assert_eq!(c.ranges()[0].start(), Ipv6Addr::from(0u128));
assert_eq!(c.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 9));
assert_eq!(c.ranges()[1].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 21));
assert_eq!(c.ranges()[1].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 49));
assert_eq!(c.ranges()[2].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 61));
assert_eq!(c.ranges()[2].end(), Ipv6Addr::from(u128::MAX));
}
#[test]
fn test_v6_complement_union_is_full() {
let a = make_v6_set(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0xff),
);
let full = a.union(&a.complement());
assert_eq!(full.len(), 1);
assert_eq!(full.ranges()[0].start(), Ipv6Addr::from(0u128));
assert_eq!(full.ranges()[0].end(), Ipv6Addr::from(u128::MAX));
}
#[test]
fn test_v6_complement_intersection_is_empty() {
let a = make_v6_set(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0xff),
);
assert!(a.intersection(&a.complement()).is_empty());
}
#[test]
fn test_v6_complement_empty() {
let empty = IpSetBuilder::<Ipv6Addr>::new().build();
let c = empty.complement();
assert_eq!(c.len(), 1);
assert_eq!(c.ranges()[0].start(), Ipv6Addr::from(0u128));
assert_eq!(c.ranges()[0].end(), Ipv6Addr::from(u128::MAX));
}
#[test]
fn test_v6_complement_double() {
let a = make_v6_set(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0xff),
);
assert_eq!(a.complement().complement(), a);
}
#[test]
fn test_v6_complement_middle_range() {
let start = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0x10);
let end = Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0x20);
let a = make_v6_set(start, end);
let c = a.complement();
assert_eq!(c.len(), 2);
assert_eq!(c.ranges()[0].start(), Ipv6Addr::from(0u128));
assert_eq!(c.ranges()[0].end(), Ipv6Addr::from(start.to_bits() - 1));
assert_eq!(c.ranges()[1].start(), Ipv6Addr::from(end.to_bits() + 1));
assert_eq!(c.ranges()[1].end(), Ipv6Addr::from(u128::MAX));
}
#[test]
fn test_v4_count_single_range() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 9));
assert_eq!(a.count(), 10);
}
#[test]
fn test_v4_count_empty() {
let empty = IpSetBuilder::<Ipv4Addr>::new().build();
assert_eq!(empty.count(), 0);
}
#[test]
fn test_v4_count_multiple_ranges() {
let mut b = IpSetBuilder::<Ipv4Addr>::new();
b.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 9),
));
b.add_range(IpRange::new(
Ipv4Addr::new(192, 168, 1, 0),
Ipv4Addr::new(192, 168, 1, 4),
));
assert_eq!(b.build().count(), 15);
}
#[test]
fn test_v4_count_single_ip() {
let mut b = IpSetBuilder::<Ipv4Addr>::new();
b.add_ip(Ipv4Addr::new(1, 2, 3, 4));
assert_eq!(b.build().count(), 1);
}
#[test]
fn test_v4_count_full_space() {
let mut b = IpSetBuilder::<Ipv4Addr>::new();
b.add_range(IpRange::new(
Ipv4Addr::new(0, 0, 0, 0),
Ipv4Addr::new(255, 255, 255, 255),
));
let set = b.build();
assert_eq!(set.count(), u32::MAX as u128 + 1);
assert_eq!(set.count_checked(), Some(u32::MAX as u128 + 1));
}
#[test]
fn test_v6_count_single_range() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 9),
);
assert_eq!(a.count(), 10);
}
#[test]
fn test_v6_count_empty() {
assert_eq!(IpSetBuilder::<Ipv6Addr>::new().build().count(), 0);
}
#[test]
fn test_v6_count_multiple_ranges() {
let mut b = IpSetBuilder::<Ipv6Addr>::new();
b.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 9),
));
b.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 54),
));
assert_eq!(b.build().count(), 15);
}
#[test]
fn test_v6_count_large_range() {
let mut b = IpSetBuilder::<Ipv6Addr>::new();
b.add_range(IpRange::new(
Ipv6Addr::from(0u128),
Ipv6Addr::from(0xffffu128),
));
let set = b.build();
assert_eq!(set.count(), 65536);
assert_eq!(set.count_checked(), Some(65536));
}
#[test]
fn test_v6_count_full_space() {
let mut b = IpSetBuilder::<Ipv6Addr>::new();
b.add_range(IpRange::new(
Ipv6Addr::from(0u128),
Ipv6Addr::from(u128::MAX),
));
let set = b.build();
assert_eq!(set.count(), u128::MAX);
assert_eq!(set.count_checked(), None);
}
#[test]
fn test_v6_count_single_ip() {
let mut b = IpSetBuilder::<Ipv6Addr>::new();
b.add_ip(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1));
assert_eq!(b.build().count(), 1);
}
#[test]
fn test_v4_subset_proper() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 50), Ipv4Addr::new(10, 0, 0, 100));
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
assert!(a.is_subset_of(&b));
assert!(!b.is_subset_of(&a));
}
#[test]
fn test_v4_superset_proper() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let b = make_v4_set(Ipv4Addr::new(10, 0, 0, 50), Ipv4Addr::new(10, 0, 0, 100));
assert!(a.is_superset_of(&b));
assert!(!b.is_superset_of(&a));
}
#[test]
fn test_v4_subset_equal() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
assert!(a.is_subset_of(&a));
assert!(a.is_superset_of(&a));
}
#[test]
fn test_v4_subset_disjoint() {
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let b = make_v4_set(
Ipv4Addr::new(192, 168, 1, 0),
Ipv4Addr::new(192, 168, 1, 255),
);
assert!(!a.is_subset_of(&b));
assert!(!b.is_subset_of(&a));
}
#[test]
fn test_v4_empty_subset_of_any() {
let empty = IpSetBuilder::<Ipv4Addr>::new().build();
let a = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
assert!(empty.is_subset_of(&a));
assert!(empty.is_subset_of(&empty));
assert!(a.is_superset_of(&empty));
}
#[test]
fn test_v6_subset_proper() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50),
);
assert!(a.is_subset_of(&b));
assert!(!b.is_subset_of(&a));
}
#[test]
fn test_v6_superset_proper() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
);
assert!(a.is_superset_of(&b));
assert!(!b.is_superset_of(&a));
}
#[test]
fn test_v6_subset_equal() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50),
);
assert!(a.is_subset_of(&a));
assert!(a.is_superset_of(&a));
}
#[test]
fn test_v6_subset_disjoint() {
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
);
let b = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 30),
);
assert!(!a.is_subset_of(&b));
assert!(!b.is_subset_of(&a));
}
#[test]
fn test_v6_empty_subset_of_any() {
let empty = IpSetBuilder::<Ipv6Addr>::new().build();
let a = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50),
);
assert!(empty.is_subset_of(&a));
assert!(empty.is_subset_of(&empty));
assert!(a.is_superset_of(&empty));
}
#[test]
fn test_v4_from_iter_ranges() {
let ranges = vec![
IpRange::new(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255)),
IpRange::new(
Ipv4Addr::new(192, 168, 1, 0),
Ipv4Addr::new(192, 168, 1, 255),
),
];
let builder: IpSetBuilder<Ipv4Addr> = ranges.into_iter().collect();
let set = builder.build();
assert_eq!(set.len(), 2);
assert!(set.contains_ip(Ipv4Addr::new(10, 0, 0, 1)));
assert!(set.contains_ip(Ipv4Addr::new(192, 168, 1, 1)));
}
#[test]
fn test_v4_from_iter_prefixes() {
let prefixes = vec![
IpPrefix::new(Ipv4Addr::new(10, 0, 0, 0), 8).unwrap(),
IpPrefix::new(Ipv4Addr::new(192, 168, 0, 0), 16).unwrap(),
];
let builder: IpSetBuilder<Ipv4Addr> = prefixes.into_iter().collect();
let set = builder.build();
assert!(set.contains_ip(Ipv4Addr::new(10, 1, 2, 3)));
assert!(set.contains_ip(Ipv4Addr::new(192, 168, 1, 100)));
assert!(!set.contains_ip(Ipv4Addr::new(172, 16, 0, 1)));
}
#[test]
fn test_v4_from_iter_ranges_merges_adjacent() {
let ranges = vec![
IpRange::new(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 127)),
IpRange::new(Ipv4Addr::new(10, 0, 0, 128), Ipv4Addr::new(10, 0, 0, 255)),
];
let set: IpSetBuilder<Ipv4Addr> = ranges.into_iter().collect();
let set = set.build();
assert_eq!(set.len(), 1);
assert_eq!(set.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 0));
assert_eq!(set.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 255));
}
#[test]
fn test_v6_from_iter_prefixes() {
let prefixes = vec![
IpPrefix::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0), 32).unwrap(),
IpPrefix::new(Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 0), 32).unwrap(),
];
let builder: IpSetBuilder<Ipv6Addr> = prefixes.into_iter().collect();
let set = builder.build();
assert!(set.contains_ip(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)));
assert!(set.contains_ip(Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 1)));
assert!(!set.contains_ip(Ipv6Addr::new(0x2001, 0xdba, 0, 0, 0, 0, 0, 1)));
}
#[test]
fn test_v6_from_iter_ranges_merges_adjacent() {
let ranges = vec![
IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x7f),
),
IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x80),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0xff),
),
];
let set: IpSetBuilder<Ipv6Addr> = ranges.into_iter().collect();
let set = set.build();
assert_eq!(set.len(), 1);
assert_eq!(set.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(set.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0xff));
}
#[test]
fn test_v6_from_iter_ranges() {
let ranges = vec![IpRange::new(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0xff),
)];
let builder: IpSetBuilder<Ipv6Addr> = ranges.into_iter().collect();
let set = builder.build();
assert_eq!(set.len(), 1);
assert!(set.contains_ip(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0x42)));
}
#[test]
fn test_v4_into_iter_ref_yields_ranges() {
let set = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let collected: Vec<_> = (&set).into_iter().collect();
assert_eq!(collected.len(), 1);
assert_eq!(*collected[0], IpRange::new(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255)));
}
#[test]
fn test_v4_for_loop_ref() {
let set = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let mut count = 0;
for _range in &set {
count += 1;
}
assert_eq!(count, 1);
}
#[test]
fn test_v4_into_iter_consuming_yields_ranges() {
let set = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let collected: Vec<IpRange<Ipv4Addr>> = set.into_iter().collect();
assert_eq!(collected.len(), 1);
assert_eq!(collected[0], IpRange::new(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255)));
}
#[test]
fn test_v4_into_iter_empty() {
let set = IpSetBuilder::<Ipv4Addr>::new().build();
assert_eq!((&set).into_iter().count(), 0);
assert_eq!(set.into_iter().count(), 0);
}
#[test]
fn test_v4_into_iter_multi_range() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 10)));
builder.add_range(IpRange::new(Ipv4Addr::new(192, 168, 1, 0), Ipv4Addr::new(192, 168, 1, 10)));
let set = builder.build();
let starts: Vec<Ipv4Addr> = (&set).into_iter().map(|r| r.start()).collect();
assert_eq!(starts, vec![Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(192, 168, 1, 0)]);
}
#[test]
fn test_v4_iter_adapter_chain() {
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 10)));
builder.add_range(IpRange::new(Ipv4Addr::new(10, 0, 1, 0), Ipv4Addr::new(10, 0, 1, 5)));
builder.add_range(IpRange::new(Ipv4Addr::new(192, 168, 1, 0), Ipv4Addr::new(192, 168, 1, 255)));
let set = builder.build();
let count = (&set).into_iter().filter(|r| r.start().octets()[0] == 10).count();
assert_eq!(count, 2);
}
#[test]
fn test_v6_for_loop_ref() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
let set = builder.build();
let mut count = 0;
for _r in &set {
count += 1;
}
assert_eq!(count, 1);
}
#[test]
fn test_v6_into_iter_consuming_yields_ranges() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
let set = builder.build();
let ranges: Vec<_> = set.into_iter().collect();
assert_eq!(ranges.len(), 1);
assert_eq!(ranges[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(ranges[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10));
}
#[test]
fn test_v6_into_iter_empty() {
let empty = IpSetBuilder::<Ipv6Addr>::new().build();
let ranges: Vec<_> = empty.into_iter().collect();
assert!(ranges.is_empty());
}
#[test]
fn test_v6_into_iter_multi_range() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 30),
));
let set = builder.build();
let ranges: Vec<_> = set.into_iter().collect();
assert_eq!(ranges.len(), 2);
}
#[test]
fn test_v6_iter_adapter_chain() {
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 10),
));
builder.add_range(IpRange::new(
Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 10),
));
builder.add_range(IpRange::new(
Ipv6Addr::new(0x2002, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2002, 0, 0, 0, 0, 0, 0, 10),
));
let set = builder.build();
let count = (&set)
.into_iter()
.filter(|r| r.start().segments()[0] == 0x2001)
.count();
assert_eq!(count, 2);
}
#[test]
fn test_v6_into_iter_ref() {
let range = IpRange::new(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0xff),
);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(range);
let set = builder.build();
let collected: Vec<_> = (&set).into_iter().collect();
assert_eq!(collected.len(), 1);
assert_eq!(*collected[0], range);
}
#[test]
fn test_v4_add_ipset_disjoint() {
let other = make_v4_set(
Ipv4Addr::new(192, 168, 1, 0),
Ipv4Addr::new(192, 168, 1, 255),
);
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 255),
));
builder.add_ipset(&other);
let set = builder.build();
assert_eq!(set.len(), 2);
assert!(set.contains_ip(Ipv4Addr::new(10, 0, 0, 1)));
assert!(set.contains_ip(Ipv4Addr::new(192, 168, 1, 1)));
}
#[test]
fn test_v4_add_ipset_overlapping() {
let other = make_v4_set(Ipv4Addr::new(10, 0, 0, 100), Ipv4Addr::new(10, 0, 1, 255));
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 200),
));
builder.add_ipset(&other);
let set = builder.build();
assert_eq!(set.len(), 1);
assert_eq!(set.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 0));
assert_eq!(set.ranges()[0].end(), Ipv4Addr::new(10, 0, 1, 255));
}
#[test]
fn test_v4_add_ipset_empty() {
let empty = IpSetBuilder::<Ipv4Addr>::new().build();
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 255),
));
builder.add_ipset(&empty);
let set = builder.build();
assert_eq!(set.len(), 1);
}
#[test]
fn test_v6_add_ipset_overlapping() {
let other = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 30),
);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
builder.add_ipset(&other);
let set = builder.build();
assert_eq!(set.len(), 1);
assert_eq!(set.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(set.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 30));
}
#[test]
fn test_v6_add_ipset_empty() {
let empty = IpSetBuilder::<Ipv6Addr>::new().build();
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.add_ipset(&empty);
assert_eq!(builder.build().len(), 1);
}
#[test]
fn test_v6_add_ipset() {
let other = make_v6_set(
Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 0xff),
);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0xff),
));
builder.add_ipset(&other);
let set = builder.build();
assert_eq!(set.len(), 2);
assert!(set.contains_ip(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)));
assert!(set.contains_ip(Ipv6Addr::new(0x2001, 0xdb9, 0, 0, 0, 0, 0, 1)));
}
#[test]
fn test_v6_remove_ipset_exact() {
let to_remove = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.remove_ipset(&to_remove);
assert!(builder.build().is_empty());
}
#[test]
fn test_v6_remove_ipset_partial() {
let to_remove = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
builder.remove_ipset(&to_remove);
let set = builder.build();
assert_eq!(set.len(), 1);
assert_eq!(set.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 11));
assert_eq!(set.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20));
}
#[test]
fn test_v6_remove_ipset_disjoint() {
let to_remove = make_v6_set(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 60),
);
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
builder.remove_ipset(&to_remove);
let set = builder.build();
assert_eq!(set.len(), 1);
assert_eq!(set.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(set.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20));
}
#[test]
fn test_v6_remove_ipset_empty() {
let empty = IpSetBuilder::<Ipv6Addr>::new().build();
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
));
builder.remove_ipset(&empty);
assert_eq!(builder.build().len(), 1);
}
#[test]
fn test_v6_remove_ipset_multi_range() {
let mut rb = IpSetBuilder::<Ipv6Addr>::new();
rb.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 10),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 20),
));
rb.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 50),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 60),
));
let to_remove = rb.build();
let mut builder = IpSetBuilder::<Ipv6Addr>::new();
builder.add_range(IpRange::new(
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 100),
));
builder.remove_ipset(&to_remove);
let set = builder.build();
assert_eq!(set.len(), 3);
assert_eq!(set.ranges()[0].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
assert_eq!(set.ranges()[0].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 9));
assert_eq!(set.ranges()[1].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 21));
assert_eq!(set.ranges()[1].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 49));
assert_eq!(set.ranges()[2].start(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 61));
assert_eq!(set.ranges()[2].end(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 100));
}
#[test]
fn test_v4_remove_ipset_exact() {
let to_remove = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 255));
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 255),
));
builder.remove_ipset(&to_remove);
assert!(builder.build().is_empty());
}
#[test]
fn test_v4_remove_ipset_partial() {
let to_remove = make_v4_set(Ipv4Addr::new(10, 0, 0, 0), Ipv4Addr::new(10, 0, 0, 127));
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 255),
));
builder.remove_ipset(&to_remove);
let set = builder.build();
assert_eq!(set.len(), 1);
assert_eq!(set.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 128));
assert_eq!(set.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 255));
}
#[test]
fn test_v4_remove_ipset_disjoint() {
let to_remove = make_v4_set(
Ipv4Addr::new(192, 168, 1, 0),
Ipv4Addr::new(192, 168, 1, 255),
);
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 255),
));
builder.remove_ipset(&to_remove);
let set = builder.build();
assert_eq!(set.len(), 1);
assert_eq!(set.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 0));
assert_eq!(set.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 255));
}
#[test]
fn test_v4_remove_ipset_empty() {
let empty = IpSetBuilder::<Ipv4Addr>::new().build();
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 255),
));
builder.remove_ipset(&empty);
let set = builder.build();
assert_eq!(set.len(), 1);
}
#[test]
fn test_v4_remove_ipset_multi_range() {
let mut rb = IpSetBuilder::<Ipv4Addr>::new();
rb.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 10),
Ipv4Addr::new(10, 0, 0, 20),
));
rb.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 50),
Ipv4Addr::new(10, 0, 0, 60),
));
let to_remove = rb.build();
let mut builder = IpSetBuilder::<Ipv4Addr>::new();
builder.add_range(IpRange::new(
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 255),
));
builder.remove_ipset(&to_remove);
let set = builder.build();
assert_eq!(set.len(), 3);
assert_eq!(set.ranges()[0].start(), Ipv4Addr::new(10, 0, 0, 0));
assert_eq!(set.ranges()[0].end(), Ipv4Addr::new(10, 0, 0, 9));
assert_eq!(set.ranges()[1].start(), Ipv4Addr::new(10, 0, 0, 21));
assert_eq!(set.ranges()[1].end(), Ipv4Addr::new(10, 0, 0, 49));
assert_eq!(set.ranges()[2].start(), Ipv4Addr::new(10, 0, 0, 61));
assert_eq!(set.ranges()[2].end(), Ipv4Addr::new(10, 0, 0, 255));
}
}