use core::{
cmp::Ordering,
net::{
IpAddr,
Ipv4Addr,
Ipv6Addr,
},
str::FromStr,
};
use crate::{
errors::NetworkParseError,
Inet,
IpInet,
Ipv4Inet,
Ipv6Inet,
};
fn test_v4(
s: &'static str,
addr: Ipv4Addr,
first_addr: Ipv4Addr,
last_addr: Ipv4Addr,
mask: Ipv4Addr,
l: u8,
) {
assert_eq!(
s.parse::<Ipv4Inet>().unwrap(),
Ipv4Inet {
address: addr,
network_length: l
},
"internal data through Ipv4Inet"
);
assert_eq!(
s.parse::<Ipv4Inet>().unwrap().address(),
addr,
"address through Ipv4Inet"
);
assert_eq!(
s.parse::<Ipv4Inet>().unwrap().first_address(),
first_addr,
"first address through Ipv4Inet"
);
assert_eq!(
s.parse::<Ipv4Inet>().unwrap().network().first_address(),
first_addr,
"first address through Ipv4Inet -> network"
);
assert_eq!(
s.parse::<Ipv4Inet>().unwrap().last_address(),
last_addr,
"last address through Ipv4Inet"
);
assert_eq!(
s.parse::<Ipv4Inet>().unwrap().network().last_address(),
last_addr,
"last address through Ipv4Inet -> network"
);
assert_eq!(
s.parse::<Ipv4Inet>().unwrap().mask(),
mask,
"mask through Ipv4Inet"
);
assert_eq!(
s.parse::<IpInet>().unwrap(),
IpInet::V4(Ipv4Inet {
address: addr,
network_length: l
}),
"internal data through IpInet"
);
assert_eq!(
s.parse::<IpInet>().unwrap().address(),
IpAddr::V4(addr),
"address through IpInet"
);
assert_eq!(
s.parse::<IpInet>().unwrap().first_address(),
IpAddr::V4(first_addr),
"first address through IpInet"
);
assert_eq!(
s.parse::<IpInet>().unwrap().network().first_address(),
IpAddr::V4(first_addr),
"first address through IpInet -> network"
);
assert_eq!(
s.parse::<IpInet>().unwrap().last_address(),
IpAddr::V4(last_addr),
"last address through IpInet"
);
assert_eq!(
s.parse::<IpInet>().unwrap().network().last_address(),
IpAddr::V4(last_addr),
"last address through IpInet -> network"
);
assert_eq!(
s.parse::<IpInet>().unwrap().mask(),
IpAddr::V4(mask),
"mask through IpInet"
);
}
fn test_v4_contains(s: &'static str, addr: Ipv4Addr) {
let c1 = s.parse::<Ipv4Inet>().unwrap();
assert!(
c1.contains(&addr),
"{:?} must include {:?} (through Ipv4Inet)",
c1,
addr
);
let c2 = s.parse::<IpInet>().unwrap();
assert!(
c2.contains(&IpAddr::V4(addr)),
"{:?} must include {:?} (through IpInet)",
c2,
addr
);
}
fn test_v4_contains_not(s: &'static str, addr: Ipv4Addr) {
let c1 = s.parse::<Ipv4Inet>().unwrap();
assert!(
!c1.contains(&addr),
"{:?} must not include {:?} (through Ipv4Inet)",
c1,
addr
);
let c2 = s.parse::<IpInet>().unwrap();
assert!(
!c2.contains(&IpAddr::V4(addr)),
"{:?} must not include {:?} (through IpInet)",
c2,
addr
);
}
fn test_v6(
s: &'static str,
addr: Ipv6Addr,
first_addr: Ipv6Addr,
last_addr: Ipv6Addr,
mask: Ipv6Addr,
l: u8,
) {
assert_eq!(
s.parse::<Ipv6Inet>().unwrap(),
Ipv6Inet {
address: addr,
network_length: l
},
"internal data through Ipv6Inet"
);
assert_eq!(
s.parse::<Ipv6Inet>().unwrap().address(),
addr,
"address through Ipv6Inet"
);
assert_eq!(
s.parse::<Ipv6Inet>().unwrap().first_address(),
first_addr,
"first address through Ipv6Inet"
);
assert_eq!(
s.parse::<Ipv6Inet>().unwrap().network().first_address(),
first_addr,
"first address through Ipv6Inet -> network"
);
assert_eq!(
s.parse::<Ipv6Inet>().unwrap().last_address(),
last_addr,
"last address through Ipv6Inet"
);
assert_eq!(
s.parse::<Ipv6Inet>().unwrap().network().last_address(),
last_addr,
"last address through Ipv6Inet -> network"
);
assert_eq!(
s.parse::<Ipv6Inet>().unwrap().mask(),
mask,
"mask through Ipv6Inet"
);
assert_eq!(
s.parse::<IpInet>().unwrap(),
IpInet::V6(Ipv6Inet {
address: addr,
network_length: l
}),
"internal data through IpInet"
);
assert_eq!(
s.parse::<IpInet>().unwrap().address(),
IpAddr::V6(addr),
"address through IpInet"
);
assert_eq!(
s.parse::<IpInet>().unwrap().first_address(),
IpAddr::V6(first_addr),
"first address through IpInet"
);
assert_eq!(
s.parse::<IpInet>().unwrap().network().first_address(),
IpAddr::V6(first_addr),
"first address through IpInet -> network"
);
assert_eq!(
s.parse::<IpInet>().unwrap().last_address(),
IpAddr::V6(last_addr),
"last address through IpInet"
);
assert_eq!(
s.parse::<IpInet>().unwrap().network().last_address(),
IpAddr::V6(last_addr),
"last address through IpInet -> network"
);
assert_eq!(
s.parse::<IpInet>().unwrap().mask(),
IpAddr::V6(mask),
"mask through IpInet"
);
}
fn test_v6_contains(s: &'static str, addr: Ipv6Addr) {
let c1 = s.parse::<Ipv6Inet>().unwrap();
assert!(
c1.contains(&addr),
"{:?} must include {:?} (through Ipv6Inet)",
c1,
addr
);
let c2 = s.parse::<IpInet>().unwrap();
assert!(
c2.contains(&IpAddr::V6(addr)),
"{:?} must include {:?} (through IpInet)",
c2,
addr
);
}
fn test_v6_contains_not(s: &'static str, addr: Ipv6Addr) {
let c1 = s.parse::<Ipv6Inet>().unwrap();
assert!(
!c1.contains(&addr),
"{:?} must not include {:?} (through Ipv6Inet)",
c1,
addr
);
let c2 = s.parse::<IpInet>().unwrap();
assert!(
!c2.contains(&IpAddr::V6(addr)),
"{:?} must not include {:?} (through IpInet)",
c2,
addr
);
}
fn test_v4_order(o: Ordering, a: &'static str, b: &'static str) {
let r1 = a
.parse::<Ipv4Inet>()
.unwrap()
.cmp(&b.parse::<Ipv4Inet>().unwrap());
assert!(
o == r1,
"Unexpected comparison outcome '{:?}' for {:?} <=> {:?}, expected '{:?}' (through Ipv4Inet)",
r1,
a,
b,
o
);
let r2 = a
.parse::<IpInet>()
.unwrap()
.cmp(&b.parse::<IpInet>().unwrap());
assert!(
o == r2,
"Unexpected comparison outcome '{:?}' for {:?} <=> {:?}, expected '{:?}' (through IpInet)",
r2,
a,
b,
o
);
if o == Ordering::Less {
test_v4_order(Ordering::Greater, b, a);
}
}
fn test_v6_order(o: Ordering, a: &'static str, b: &'static str) {
let r1 = a
.parse::<Ipv6Inet>()
.unwrap()
.cmp(&b.parse::<Ipv6Inet>().unwrap());
assert!(
o == r1,
"Unexpected comparison outcome '{:?}' for {:?} <=> {:?}, expected '{:?}' (through Ipv6Inet)",
r1,
a,
b,
o
);
let r2 = a
.parse::<IpInet>()
.unwrap()
.cmp(&b.parse::<IpInet>().unwrap());
assert!(
o == r2,
"Unexpected comparison outcome '{:?}' for {:?} <=> {:?}, expected '{:?}' (through IpInet)",
r2,
a,
b,
o
);
if o == Ordering::Less {
test_v6_order(Ordering::Greater, b, a);
}
}
fn test_order(o: Ordering, a: &'static str, b: &'static str) {
let r = a
.parse::<IpInet>()
.unwrap()
.cmp(&b.parse::<IpInet>().unwrap());
assert!(
o == r,
"Unexpected comparison outcome '{:?}' for {:?} <=> {:?}, expected '{:?}' (through IpCidr)",
r,
a,
b,
o
);
if o == Ordering::Less {
test_order(Ordering::Greater, b, a);
}
}
#[test]
#[should_panic(
expected = "invalid length for network: Network length 33 is too long for Ipv4 (maximum: 32)"
)]
fn parse_v4_33bit() {
"192.0.2.48/33".parse::<Ipv4Inet>().unwrap();
}
#[test]
#[should_panic(
expected = "invalid length for network: Network length 33 is too long for Ipv4 (maximum: 32)"
)]
fn parse_v4_33bit_2() {
"192.0.2.48/33".parse::<IpInet>().unwrap();
}
#[test]
fn test_v4_host_address() {
assert!("127.0.0.1/32"
.parse::<Ipv4Inet>()
.unwrap()
.is_host_address());
assert!("127.0.0.1/32".parse::<IpInet>().unwrap().is_host_address());
assert!(!"127.0.0.1/31"
.parse::<Ipv4Inet>()
.unwrap()
.is_host_address());
assert!(!"127.0.0.1/31".parse::<IpInet>().unwrap().is_host_address());
}
#[test]
fn test_v4_representations_32bit() {
assert_eq!(
format_cidr_fixed!("{}", "127.0.0.1".parse::<Ipv4Inet>().unwrap()),
"127.0.0.1"
);
assert_eq!(
format_cidr_fixed!("{}", "127.0.0.1".parse::<IpInet>().unwrap()),
"127.0.0.1"
);
assert_eq!(
format_cidr_fixed!("{:?}", "127.0.0.1".parse::<Ipv4Inet>().unwrap()),
"127.0.0.1/32"
);
assert_eq!(
format_cidr_fixed!("{:?}", "127.0.0.1".parse::<IpInet>().unwrap()),
"V4(127.0.0.1/32)"
);
}
#[test]
fn test_v4_representations_8bit() {
assert_eq!(
format_cidr_fixed!("{}", "10.0.0.0/8".parse::<Ipv4Inet>().unwrap()),
"10.0.0.0/8"
);
assert_eq!(
format_cidr_fixed!("{}", "10.0.0.0/8".parse::<IpInet>().unwrap()),
"10.0.0.0/8"
);
assert_eq!(
format_cidr_fixed!("{:?}", "10.0.0.0/8".parse::<Ipv4Inet>().unwrap()),
"10.0.0.0/8"
);
assert_eq!(
format_cidr_fixed!("{:?}", "10.0.0.0/8".parse::<IpInet>().unwrap()),
"V4(10.0.0.0/8)"
);
assert_eq!(
format_cidr_fixed!("{}", "10.4.3.2/8".parse::<Ipv4Inet>().unwrap()),
"10.4.3.2/8"
);
assert_eq!(
format_cidr_fixed!("{}", "10.4.3.2/8".parse::<IpInet>().unwrap()),
"10.4.3.2/8"
);
assert_eq!(
format_cidr_fixed!("{:?}", "10.4.3.2/8".parse::<Ipv4Inet>().unwrap()),
"10.4.3.2/8"
);
assert_eq!(
format_cidr_fixed!("{:?}", "10.4.3.2/8".parse::<IpInet>().unwrap()),
"V4(10.4.3.2/8)"
);
}
#[test]
fn test_v4_representations_0bit() {
assert_eq!(
format_cidr_fixed!("{}", "0.0.0.0/0".parse::<Ipv4Inet>().unwrap()),
"0.0.0.0/0"
);
assert_eq!(
format_cidr_fixed!("{}", "0.0.0.0/0".parse::<IpInet>().unwrap()),
"0.0.0.0/0"
);
assert_eq!(
format_cidr_fixed!("{:?}", "0.0.0.0/0".parse::<Ipv4Inet>().unwrap()),
"0.0.0.0/0"
);
assert_eq!(
format_cidr_fixed!("{:?}", "0.0.0.0/0".parse::<IpInet>().unwrap()),
"V4(0.0.0.0/0)"
);
assert_eq!(
format_cidr_fixed!("{}", "192.0.2.0/0".parse::<Ipv4Inet>().unwrap()),
"192.0.2.0/0"
);
assert_eq!(
format_cidr_fixed!("{}", "192.0.2.0/0".parse::<IpInet>().unwrap()),
"192.0.2.0/0"
);
assert_eq!(
format_cidr_fixed!("{:?}", "192.0.2.0/0".parse::<Ipv4Inet>().unwrap()),
"192.0.2.0/0"
);
assert_eq!(
format_cidr_fixed!("{:?}", "192.0.2.0/0".parse::<IpInet>().unwrap()),
"V4(192.0.2.0/0)"
);
}
#[test]
fn parse_v4_localhost() {
test_v4(
"127.0.0.1",
Ipv4Addr::new(127, 0, 0, 1),
Ipv4Addr::new(127, 0, 0, 1),
Ipv4Addr::new(127, 0, 0, 1),
Ipv4Addr::new(255, 255, 255, 255),
32,
);
}
#[test]
fn parse_v4_localhost_32() {
test_v4(
"127.0.0.1/32",
Ipv4Addr::new(127, 0, 0, 1),
Ipv4Addr::new(127, 0, 0, 1),
Ipv4Addr::new(127, 0, 0, 1),
Ipv4Addr::new(255, 255, 255, 255),
32,
);
}
#[test]
fn parse_v4_28bit() {
test_v4(
"192.0.2.48/28",
Ipv4Addr::new(192, 0, 2, 48),
Ipv4Addr::new(192, 0, 2, 48),
Ipv4Addr::new(192, 0, 2, 63),
Ipv4Addr::new(255, 255, 255, 240),
28,
);
}
#[test]
fn parse_v4_23bit() {
test_v4(
"192.0.2.0/23",
Ipv4Addr::new(192, 0, 2, 0),
Ipv4Addr::new(192, 0, 2, 0),
Ipv4Addr::new(192, 0, 3, 255),
Ipv4Addr::new(255, 255, 254, 0),
23,
);
}
#[test]
fn parse_v4_23bit_non_zero_host_bits() {
test_v4(
"192.0.3.0/23",
Ipv4Addr::new(192, 0, 3, 0),
Ipv4Addr::new(192, 0, 2, 0),
Ipv4Addr::new(192, 0, 3, 255),
Ipv4Addr::new(255, 255, 254, 0),
23,
);
}
#[test]
fn parse_v4_17bit() {
test_v4(
"192.0.128.0/17",
Ipv4Addr::new(192, 0, 128, 0),
Ipv4Addr::new(192, 0, 128, 0),
Ipv4Addr::new(192, 0, 255, 255),
Ipv4Addr::new(255, 255, 128, 0),
17,
);
}
#[test]
fn parse_v4_17bit_non_zero_host_bits() {
test_v4(
"192.0.192.0/17",
Ipv4Addr::new(192, 0, 192, 0),
Ipv4Addr::new(192, 0, 128, 0),
Ipv4Addr::new(192, 0, 255, 255),
Ipv4Addr::new(255, 255, 128, 0),
17,
);
}
#[test]
fn parse_v4_8bit() {
test_v4(
"10.0.0.0/8",
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 0, 0, 0),
Ipv4Addr::new(10, 255, 255, 255),
Ipv4Addr::new(255, 0, 0, 0),
8,
);
}
#[test]
fn parse_v4_0bit() {
test_v4(
"0.0.0.0/0",
Ipv4Addr::new(0, 0, 0, 0),
Ipv4Addr::new(0, 0, 0, 0),
Ipv4Addr::new(255, 255, 255, 255),
Ipv4Addr::new(0, 0, 0, 0),
0,
);
}
#[test]
fn parse_v4_non_zero_host_bits() {
test_v4(
"10.1.1.1/24",
Ipv4Addr::new(10, 1, 1, 1),
Ipv4Addr::new(10, 1, 1, 0),
Ipv4Addr::new(10, 1, 1, 255),
Ipv4Addr::new(255, 255, 255, 0),
24,
);
}
#[test]
fn contains_v4_24bit() {
test_v4_contains("192.0.2.0/24", Ipv4Addr::new(0xc0, 0x00, 0x02, 0x01));
}
#[test]
fn contains_not_v4_24bit() {
test_v4_contains_not("192.0.2.0/24", Ipv4Addr::new(0x40, 0x00, 0x02, 0x01));
}
#[test]
fn contains_not_v4_24bit_2() {
test_v4_contains_not("192.0.2.0/24", Ipv4Addr::new(0xc0, 0x00, 0x03, 0x01));
}
#[test]
#[should_panic(
expected = "invalid length for network: Network length 129 is too long for Ipv6 (maximum: 128)"
)]
fn parse_v6_129bit() {
"2001:DB8::/129".parse::<Ipv6Inet>().unwrap();
}
#[test]
#[should_panic(
expected = "invalid length for network: Network length 129 is too long for Ipv6 (maximum: 128)"
)]
fn parse_v6_33bit_2() {
"2001:DB8::/129".parse::<IpInet>().unwrap();
}
#[test]
fn test_v6_host_address() {
assert!("::/128".parse::<Ipv6Inet>().unwrap().is_host_address());
assert!("::/128".parse::<IpInet>().unwrap().is_host_address());
assert!(!"::/127".parse::<Ipv6Inet>().unwrap().is_host_address());
assert!(!"::/127".parse::<IpInet>().unwrap().is_host_address());
}
#[test]
fn test_v6_representations_128bit() {
assert_eq!(
format_cidr_fixed!("{}", "::".parse::<Ipv6Inet>().unwrap()),
"::"
);
assert_eq!(
format_cidr_fixed!("{}", "::".parse::<IpInet>().unwrap()),
"::"
);
assert_eq!(
format_cidr_fixed!("{:?}", "::".parse::<Ipv6Inet>().unwrap()),
"::/128"
);
assert_eq!(
format_cidr_fixed!("{:?}", "::".parse::<IpInet>().unwrap()),
"V6(::/128)"
);
}
#[test]
fn test_v6_representations_64bit() {
assert_eq!(
format_cidr_fixed!("{}", "2001:DB8:1234:5678::/64".parse::<Ipv6Inet>().unwrap()),
"2001:db8:1234:5678::/64"
);
assert_eq!(
format_cidr_fixed!("{}", "2001:DB8:1234:5678::/64".parse::<IpInet>().unwrap()),
"2001:db8:1234:5678::/64"
);
assert_eq!(
format_cidr_fixed!(
"{:?}",
"2001:DB8:1234:5678::/64".parse::<Ipv6Inet>().unwrap()
),
"2001:db8:1234:5678::/64"
);
assert_eq!(
format_cidr_fixed!("{:?}", "2001:DB8:1234:5678::/64".parse::<IpInet>().unwrap()),
"V6(2001:db8:1234:5678::/64)"
);
assert_eq!(
format_cidr_fixed!(
"{}",
"2001:DB8:1234:5678:1:2:3:4/64".parse::<Ipv6Inet>().unwrap()
),
"2001:db8:1234:5678:1:2:3:4/64"
);
assert_eq!(
format_cidr_fixed!(
"{}",
"2001:DB8:1234:5678:1:2:3:4/64".parse::<IpInet>().unwrap()
),
"2001:db8:1234:5678:1:2:3:4/64"
);
assert_eq!(
format_cidr_fixed!(
"{:?}",
"2001:DB8:1234:5678:1:2:3:4/64".parse::<Ipv6Inet>().unwrap()
),
"2001:db8:1234:5678:1:2:3:4/64"
);
assert_eq!(
format_cidr_fixed!(
"{:?}",
"2001:DB8:1234:5678:1:2:3:4/64".parse::<IpInet>().unwrap()
),
"V6(2001:db8:1234:5678:1:2:3:4/64)"
);
}
#[test]
fn test_v6_representations_0bit() {
assert_eq!(
format_cidr_fixed!("{}", "::/0".parse::<Ipv6Inet>().unwrap()),
"::/0"
);
assert_eq!(
format_cidr_fixed!("{}", "::/0".parse::<IpInet>().unwrap()),
"::/0"
);
assert_eq!(
format_cidr_fixed!("{:?}", "::/0".parse::<Ipv6Inet>().unwrap()),
"::/0"
);
assert_eq!(
format_cidr_fixed!("{:?}", "::/0".parse::<IpInet>().unwrap()),
"V6(::/0)"
);
assert_eq!(
format_cidr_fixed!(
"{}",
"2001:DB8:1234:5678:1:2:3:4/0".parse::<Ipv6Inet>().unwrap()
),
"2001:db8:1234:5678:1:2:3:4/0"
);
assert_eq!(
format_cidr_fixed!(
"{}",
"2001:DB8:1234:5678:1:2:3:4/0".parse::<IpInet>().unwrap()
),
"2001:db8:1234:5678:1:2:3:4/0"
);
assert_eq!(
format_cidr_fixed!(
"{:?}",
"2001:DB8:1234:5678:1:2:3:4/0".parse::<Ipv6Inet>().unwrap()
),
"2001:db8:1234:5678:1:2:3:4/0"
);
assert_eq!(
format_cidr_fixed!(
"{:?}",
"2001:DB8:1234:5678:1:2:3:4/0".parse::<IpInet>().unwrap()
),
"V6(2001:db8:1234:5678:1:2:3:4/0)"
);
}
#[test]
fn parse_v6_unspec() {
test_v6(
"::",
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(!0, !0, !0, !0, !0, !0, !0, !0),
128,
);
}
#[test]
fn parse_v6_localhost() {
test_v6(
"::1",
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(!0, !0, !0, !0, !0, !0, !0, !0),
128,
);
}
#[test]
fn parse_v6_localhost_128() {
test_v6(
"::1/128",
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
Ipv6Addr::new(!0, !0, !0, !0, !0, !0, !0, !0),
128,
);
}
#[test]
fn parse_v6_v4_124bit() {
test_v6(
"::192.168.4.48/124",
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 192 * 256 + 168, 4 * 256 + 48),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 192 * 256 + 168, 4 * 256 + 48),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 192 * 256 + 168, 4 * 256 + 63),
Ipv6Addr::new(!0, !0, !0, !0, !0, !0, !0, !0 - 15),
124,
);
}
#[test]
fn parse_v6_64bit() {
test_v6(
"2001:DB8:1234:5678::/64",
Ipv6Addr::new(0x2001, 0xdb8, 0x1234, 0x5678, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0x1234, 0x5678, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0x1234, 0x5678, !0, !0, !0, !0),
Ipv6Addr::new(!0, !0, !0, !0, 0, 0, 0, 0),
64,
);
}
#[test]
fn parse_v6_non_zero_host_bits() {
test_v6(
"2001:DB8:1234:5678:1::/64",
Ipv6Addr::new(0x2001, 0xdb8, 0x1234, 0x5678, 1, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0x1234, 0x5678, 0, 0, 0, 0),
Ipv6Addr::new(0x2001, 0xdb8, 0x1234, 0x5678, !0, !0, !0, !0),
Ipv6Addr::new(!0, !0, !0, !0, 0, 0, 0, 0),
64,
);
}
#[test]
fn parse_v6_0bit() {
test_v6(
"::/0",
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
Ipv6Addr::new(!0, !0, !0, !0, !0, !0, !0, !0),
Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
0,
);
}
#[test]
fn contains_v6_64bit() {
test_v6_contains(
"2001:DB8:1234:5678::/64",
Ipv6Addr::new(0x2001, 0xdb8, 0x1234, 0x5678, 0x1001, 2, 3, 4),
);
}
#[test]
fn contains_not_v6_64bit() {
test_v6_contains_not(
"2001:DB8:1234:5678::/64",
Ipv6Addr::new(0xa001, 0xdb8, 0x1234, 0x5678, 0x1001, 2, 3, 4),
);
}
#[test]
fn contains_not_v6_64bit_2() {
test_v6_contains_not(
"2001:DB8:1234:5678::/64",
Ipv6Addr::new(0xa001, 0xdb8, 0x1234, 0x5679, 0x1001, 2, 3, 4),
);
}
#[test]
fn order_v4() {
test_v4_order(Ordering::Equal, "192.0.2.0/24", "192.0.2.0/24");
test_v4_order(Ordering::Less, "192.0.2.0/24", "192.0.3.0/24");
test_v4_order(Ordering::Less, "192.0.2.0/24", "192.0.2.0/25");
test_v4_order(Ordering::Less, "192.0.2.0/24", "192.0.2.128/25");
test_v4_order(Ordering::Equal, "192.0.2.42/24", "192.0.2.42/24");
test_v4_order(Ordering::Less, "192.0.2.41/16", "192.0.2.42/24");
test_v4_order(Ordering::Less, "192.0.2.41/24", "192.0.2.42/24");
test_v4_order(Ordering::Less, "192.0.2.42/24", "192.0.2.42/25");
test_v4_order(Ordering::Less, "192.0.2.42/24", "192.0.2.170/25");
}
#[test]
fn order_v6() {
test_v6_order(
Ordering::Equal,
"2001:DB8:1234:5678::/64",
"2001:DB8:1234:5678::/64",
);
test_v6_order(
Ordering::Less,
"2001:DB8:1234:5678:1000::/80",
"2001:DB8:1234:5678:1001::/80",
);
test_v6_order(
Ordering::Less,
"2001:DB8:1234:5678:1000::/80",
"2001:DB8:1234:5678:1000::/81",
);
test_v6_order(
Ordering::Less,
"2001:DB8:1234:5678:1000::/80",
"2001:DB8:1234:5678:1000:8000::/81",
);
test_v6_order(
Ordering::Equal,
"2001:DB8:1234:5678::42/64",
"2001:DB8:1234:5678::42/64",
);
test_v6_order(
Ordering::Less,
"2001:DB8:1234:5678:1000::41/48",
"2001:DB8:1234:5678:1000::42/80",
);
test_v6_order(
Ordering::Less,
"2001:DB8:1234:5678:1000::41/80",
"2001:DB8:1234:5678:1000::42/80",
);
test_v6_order(
Ordering::Less,
"2001:DB8:1234:5678:1000::42/80",
"2001:DB8:1234:5678:1000::42/81",
);
test_v6_order(
Ordering::Less,
"2001:DB8:1234:5678:1000::42/80",
"2001:DB8:1234:5678:1000:8000::42/81",
);
}
#[test]
fn order() {
test_order(Ordering::Less, "192.0.2.0/24", "2001:DB8:1234:5678::/64");
}
fn test_nth<I>(a: &str, b: &str, step: u128, overflow: bool)
where
I: Inet
+ FromStr<Err = NetworkParseError>
+ core::ops::Add<u128, Output = I>
+ core::ops::Sub<u128, Output = I>,
{
let a = a.parse::<I>().unwrap();
let b = b.parse::<I>().unwrap();
assert_eq!(a.overflowing_add(step), (b, overflow));
assert_eq!(b.overflowing_sub(step), (a, overflow));
if !overflow {
assert_eq!(a + step, b);
assert_eq!(b - step, a);
}
}
#[test]
fn test_nth_v4() {
test_nth::<Ipv4Inet>("255.255.255.255/0", "0.0.0.0/0", 1, true);
test_nth::<IpInet>("255.255.255.255/0", "0.0.0.0/0", 1, true);
test_nth::<Ipv4Inet>("255.255.255.255/0", "127.0.0.1/0", 0x7f000002, true);
test_nth::<IpInet>("255.255.255.255/0", "127.0.0.1/0", 0x7f000002, true);
test_nth::<Ipv4Inet>("192.0.2.23/24", "192.0.2.42/24", 19, false);
test_nth::<IpInet>("192.0.2.23/24", "192.0.2.42/24", 19, false);
test_nth::<Ipv4Inet>("192.0.2.42/24", "192.0.2.23/24", 237, true);
test_nth::<IpInet>("192.0.2.42/24", "192.0.2.23/24", 237, true);
}
#[test]
fn test_nth_v6() {
test_nth::<Ipv6Inet>("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0", "::/0", 1, true);
test_nth::<IpInet>("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0", "::/0", 1, true);
test_nth::<Ipv6Inet>(
"2001:DB8:1234:5678::23/64",
"2001:DB8:1234:5678::42/64",
0x1f,
false,
);
test_nth::<IpInet>(
"2001:DB8:1234:5678::23/64",
"2001:DB8:1234:5678::42/64",
0x1f,
false,
);
test_nth::<Ipv6Inet>(
"2001:DB8:1234:5678::42/64",
"2001:DB8:1234:5678::23/64",
(1 << 64) - 0x1f,
true,
);
test_nth::<IpInet>(
"2001:DB8:1234:5678::42/64",
"2001:DB8:1234:5678::23/64",
(1 << 64) - 0x1f,
true,
);
}