use crate::{interfaces::IpAddress, range::IpRange};
pub(crate) fn normalize<A: IpAddress>(mut ranges: Vec<IpRange<A>>) -> Vec<IpRange<A>> {
ranges.sort_by_key(|range| range.start().to_u128());
let mut merged = Vec::<IpRange<A>>::new();
for range in ranges {
match merged.last_mut() {
Some(last) if range.start().to_u128() <= last.end().to_u128().saturating_add(1) => {
if range.end().to_u128() > last.end().to_u128() {
*last = IpRange::new(last.start(), range.end());
}
}
_ => {
merged.push(range);
}
}
}
merged
}
pub(crate) fn subtract_range<A: IpAddress>(
mut ranges: Vec<IpRange<A>>,
remove: IpRange<A>,
) -> Vec<IpRange<A>> {
let start = remove.start().to_u128();
let end = remove.end().to_u128();
let mut result = Vec::new();
for stored in ranges.drain(..) {
let s = stored.start().to_u128();
let e = stored.end().to_u128();
if e < start || s > end {
result.push(stored);
} else {
if s < start {
result.push(IpRange::new(stored.start(), A::from_u128(start - 1)));
}
if e > end {
result.push(IpRange::new(A::from_u128(end + 1), stored.end()));
}
}
}
result
}