Expand description
Parse CIDR strings, aggregate, reverse, and difference IP ranges, then normalize back to CIDR notation.
Supports both IPv4 and IPv6. The core abstraction is the IpRange trait,
implemented by Ipv4Range and Ipv6Range. Operations like
.aggregate(), .reverse(), .normalize(), and .export() are provided
on Vec of either range type via the Aggregator trait.
§Quick start
Aggregate overlapping and adjacent CIDR blocks into a minimal set:
use cidr_aggregator::{parse_cidrs, Aggregator};
let (mut v4_ranges, _, _) = parse_cidrs("10.0.0.0/24\n10.0.1.0/24\n10.0.0.128/25");
// 10.0.0.0/24 and 10.0.1.0/24 are adjacent → merge to 10.0.0.0/23
// 10.0.0.128/25 is already covered by the /23 → absorbed
v4_ranges.aggregate();
// Aggregate produces a minimal set but not necessarily canonical CIDR
// blocks — normalize() is required before export().
v4_ranges.normalize();
assert_eq!(v4_ranges.export(), "10.0.0.0/23");Chain operations in a pipeline — filter reserved addresses, then reverse:
use cidr_aggregator::{parse_cidrs, Aggregator, IpRange, Ipv6Range};
let (_, v6_ranges, _) = parse_cidrs("2001:db8::/32\n64:ff9b::/96");
println!(
"{}",
v6_ranges
.aggregated()
.differenced(Ipv6Range::reserved()) // strip RFC 6890 reserved blocks
// Normalize is required to produce valid CIDR blocks after aggregation
// and difference, which may leave non-canonical ranges.
.normalized()
.reversed()
.export()
);A WASM build of this crate powers the web app at https://cidr-aggregator.pages.dev.
Re-exports§
pub use aggregator::Aggregator;pub use parser::parse_cidrs;
Modules§
- aggregator
- Operations on
Vec<R: IpRange>: aggregate, reverse, difference, normalize. - parser
- CIDR string parser.
Structs§
- Ipv4
Range - An inclusive IPv4 range
[first, last]stored asu32. - Ipv6
Range - An inclusive IPv6 range
[first, last]stored asu128.
Enums§
- Either
IpRange - Either an IPv4 or IPv6 range, used for parsing CIDR strings.
Traits§
- IpRange
- Core abstraction for an IP range.