1use std::net::{
2 AddrParseError,
3 IpAddr,
4};
5
6use crate::{
7 errors::NetworkParseError,
8 Address,
9 AnyIpCidr,
10 Cidr,
11 Inet,
12 IpCidr,
13 IpInet,
14};
15
16pub fn parse_cidr_full<C, AP, HP>(
21 s: &str,
22 address_parser: AP,
23 host_parser: HP,
24) -> Result<C, NetworkParseError>
25where
26 C: Cidr,
27 AP: FnOnce(&str) -> Result<C::Address, AddrParseError>,
28 HP: FnOnce(&str) -> Result<C, NetworkParseError>,
29{
30 match s.rfind('/') {
31 None => host_parser(s),
32 Some(pos) => C::new(address_parser(&s[0..pos])?, s[pos + 1..].parse()?),
33 }
34}
35
36pub fn parse_cidr<C, AP>(s: &str, address_parser: AP) -> Result<C, NetworkParseError>
41where
42 C: Cidr,
43 AP: Fn(&str) -> Result<C::Address, AddrParseError>,
44{
45 parse_cidr_full(s, &address_parser, |s| Ok(C::new_host(address_parser(s)?)))
46}
47
48pub fn parse_cidr_full_ignore_hostbits<C, AP, HP>(
52 s: &str,
53 address_parser: AP,
54 host_parser: HP,
55) -> Result<C, NetworkParseError>
56where
57 C: Cidr,
58 AP: FnOnce(&str) -> Result<C::Address, AddrParseError>,
59 HP: FnOnce(&str) -> Result<C, NetworkParseError>,
60{
61 match s.rfind('/') {
62 None => host_parser(s),
63 Some(pos) => {
64 let inet = <C::Address as Address>::Inet::new(
65 address_parser(&s[0..pos])?,
66 s[pos + 1..].parse()?,
67 )?;
68 Ok(inet.network())
69 },
70 }
71}
72
73pub fn parse_cidr_ignore_hostbits<C, AP>(
77 s: &str,
78 address_parser: AP,
79) -> Result<C, NetworkParseError>
80where
81 C: Cidr,
82 AP: Fn(&str) -> Result<C::Address, AddrParseError>,
83{
84 parse_cidr_full_ignore_hostbits(s, &address_parser, |s| Ok(C::new_host(address_parser(s)?)))
85}
86
87pub fn parse_any_cidr_full<AP, HP>(
93 s: &str,
94 address_parser: AP,
95 host_parser: HP,
96) -> Result<AnyIpCidr, NetworkParseError>
97where
98 AP: FnOnce(&str) -> Result<IpAddr, AddrParseError>,
99 HP: FnOnce(&str) -> Result<IpCidr, NetworkParseError>,
100{
101 if s == "any" {
102 return Ok(AnyIpCidr::Any);
103 }
104 match s.rfind('/') {
105 None => Ok(host_parser(s)?.into()),
106 Some(pos) => AnyIpCidr::new(address_parser(&s[0..pos])?, s[pos + 1..].parse()?),
107 }
108}
109
110pub fn parse_any_cidr<AP>(s: &str, address_parser: AP) -> Result<AnyIpCidr, NetworkParseError>
116where
117 AP: Fn(&str) -> Result<IpAddr, AddrParseError>,
118{
119 parse_any_cidr_full(s, &address_parser, |s| {
120 Ok(IpCidr::new_host(address_parser(s)?))
121 })
122}
123
124pub fn parse_any_cidr_full_ignore_hostbits<AP, HP>(
128 s: &str,
129 address_parser: AP,
130 host_parser: HP,
131) -> Result<AnyIpCidr, NetworkParseError>
132where
133 AP: FnOnce(&str) -> Result<IpAddr, AddrParseError>,
134 HP: FnOnce(&str) -> Result<IpCidr, NetworkParseError>,
135{
136 if s == "any" {
137 return Ok(AnyIpCidr::Any);
138 }
139 match s.rfind('/') {
140 None => Ok(host_parser(s)?.into()),
141 Some(pos) => Ok(
142 IpInet::new(address_parser(&s[0..pos])?, s[pos + 1..].parse()?)?
143 .network()
144 .into(),
145 ),
146 }
147}
148
149pub fn parse_any_cidr_ignore_hostbits<AP>(
153 s: &str,
154 address_parser: AP,
155) -> Result<AnyIpCidr, NetworkParseError>
156where
157 AP: Fn(&str) -> Result<IpAddr, AddrParseError>,
158{
159 parse_any_cidr_full_ignore_hostbits(s, &address_parser, |s| {
160 Ok(IpCidr::new_host(address_parser(s)?))
161 })
162}
163
164pub fn parse_inet_full<I, AP, HP>(
169 s: &str,
170 address_parser: AP,
171 host_parser: HP,
172) -> Result<I, NetworkParseError>
173where
174 I: Inet,
175 AP: FnOnce(&str) -> Result<I::Address, AddrParseError>,
176 HP: FnOnce(&str) -> Result<I, NetworkParseError>,
177{
178 match s.rfind('/') {
179 None => host_parser(s),
180 Some(pos) => Ok(I::new(address_parser(&s[0..pos])?, s[pos + 1..].parse()?)?),
181 }
182}
183
184pub fn parse_inet<I, AP>(s: &str, address_parser: AP) -> Result<I, NetworkParseError>
189where
190 I: Inet,
191 AP: Fn(&str) -> Result<I::Address, AddrParseError>,
192{
193 parse_inet_full(s, &address_parser, |s| Ok(I::new_host(address_parser(s)?)))
194}