netaddr2/netaddr/
fromstr.rs

1use super::{Error, NetAddr, Result};
2use crate::Netv4Addr;
3use crate::Netv6Addr;
4use core::str::FromStr;
5
6impl FromStr for NetAddr {
7	type Err = Error;
8
9	fn from_str(string: &str) -> Result<Self> {
10		let as_v4: Result<Netv4Addr> = string.parse::<Netv4Addr>();
11		let as_v6: Result<Netv6Addr> = string.parse::<Netv6Addr>();
12
13		match (as_v4, as_v6) {
14			(Ok(v4), _) => Ok(Self::V4(v4)),
15			(_, Ok(v6)) => Ok(Self::V6(v6)),
16			(Err(_e4), Err(e6)) => Err(e6),
17		}
18	}
19}
20
21#[cfg(test)]
22mod tests {
23	use super::*;
24
25	#[test]
26	fn invalid_is_safe() {
27		let _: Result<NetAddr> = "zoop".parse::<NetAddr>();
28	}
29
30	#[test]
31	fn addr_only_returns_full_bitstring() {
32		let net: NetAddr = "127.0.0.1/zoop".parse().unwrap();
33		assert_eq!(net, "127.0.0.1/32".parse().unwrap());
34		let net: NetAddr = "ff02::1/zoop".parse().unwrap();
35		assert_eq!(net, "ff02::1/128".parse().unwrap());
36	}
37
38	#[test]
39	fn non_addr_passes_out_error() {
40		let result = "zoop".parse::<NetAddr>();
41		assert_eq!(
42			result,
43			Err(Error::ParseError(
44				"could not split provided input".to_string()
45			))
46		);
47	}
48
49	mod v4 {
50		use super::NetAddr;
51		use std::net::{IpAddr, Ipv4Addr};
52
53		#[test]
54		fn cidr_32_correct_network_and_netmask() {
55			let net: NetAddr = "192.0.2.0/32".parse().unwrap();
56			assert_eq!(net.mask(), IpAddr::V4(Ipv4Addr::new(255, 255, 255, 255)));
57			assert_eq!(net.addr(), IpAddr::V4(Ipv4Addr::new(192, 0, 2, 0)));
58		}
59
60		#[test]
61		fn cidr_8_correct_network_and_netmask() {
62			let net: NetAddr = "127.0.0.1/8".parse().unwrap();
63			assert_eq!(net.mask(), IpAddr::V4(Ipv4Addr::new(255, 0, 0, 0)));
64			assert_eq!(net.addr(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 0)));
65		}
66
67		#[test]
68		fn cidr_22_correct_network_and_netmask() {
69			let net: NetAddr = "192.168.16.1/22".parse().unwrap();
70			assert_eq!(net.mask(), IpAddr::V4(Ipv4Addr::new(255, 255, 252, 0)));
71			assert_eq!(net.addr(), IpAddr::V4(Ipv4Addr::new(192, 168, 16, 0)));
72		}
73
74		#[test]
75		fn localhost_extended_correct_network_and_netmask() {
76			let net: NetAddr = "127.0.0.1 255.0.0.0".parse().unwrap();
77			assert_eq!(net.mask(), IpAddr::V4(Ipv4Addr::new(255, 0, 0, 0)));
78			assert_eq!(net.addr(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 0)));
79		}
80
81		#[test]
82		fn localhost_slashed_extended_correct_network_and_netmask() {
83			let net: NetAddr = "127.0.0.1/255.0.0.0".parse().unwrap();
84			assert_eq!(net.mask(), IpAddr::V4(Ipv4Addr::new(255, 0, 0, 0)));
85			assert_eq!(net.addr(), IpAddr::V4(Ipv4Addr::new(127, 0, 0, 0)));
86		}
87	}
88
89	mod v6 {
90		use super::NetAddr;
91		use std::net::{IpAddr, Ipv6Addr};
92
93		#[test]
94		fn cidr_8_correct_network_and_netmask() {
95			let net: NetAddr = "ff02::1/8".parse().unwrap();
96			assert_eq!(
97				net.mask(),
98				IpAddr::V6(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0x0000))
99			);
100			assert_eq!(
101				net.addr(),
102				IpAddr::V6(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0x0000))
103			);
104		}
105
106		#[test]
107		fn cidr_128_correct_network_and_netmask() {
108			let net: NetAddr = "ff02::1/128".parse().unwrap();
109			assert_eq!(
110				net.mask(),
111				IpAddr::V6(Ipv6Addr::new(
112					0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
113				))
114			);
115			assert_eq!(
116				net.addr(),
117				IpAddr::V6(Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 0x0001))
118			);
119		}
120
121		#[test]
122		fn extended_correct_network_and_netmask() {
123			let net: NetAddr = "ff02::1 ffff::0".parse().unwrap();
124			assert_eq!(
125				net.mask(),
126				IpAddr::V6(Ipv6Addr::new(0xffff, 0, 0, 0, 0, 0, 0, 0))
127			);
128			assert_eq!(
129				net.addr(),
130				IpAddr::V6(Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 0))
131			);
132		}
133
134		#[test]
135		fn extended_slashed_correct_network_and_netmask() {
136			let net: NetAddr = "ff02::1/128".parse().unwrap();
137			assert_eq!(
138				net.mask(),
139				IpAddr::V6(Ipv6Addr::new(
140					0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
141				))
142			);
143			assert_eq!(
144				net.addr(),
145				IpAddr::V6(Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 0x0001))
146			);
147		}
148	}
149}