Parse a CIDR like `"10.42.0.0/16"` or `"fd00::/8"`. Returns `None` if the input doesn't match `IP/prefix` with a valid prefix width.
(s: &str)
| 195 | /// Parse a CIDR like `"10.42.0.0/16"` or `"fd00::/8"`. Returns `None` |
| 196 | /// if the input doesn't match `IP/prefix` with a valid prefix width. |
| 197 | pub fn parse(s: &str) -> Option<Self> { |
| 198 | let (ip_str, prefix_str) = s.split_once('/')?; |
| 199 | let prefix: u8 = prefix_str.parse().ok()?; |
| 200 | let ip: IpAddr = ip_str.parse().ok()?; |
| 201 | let (bits, is_v4) = match ip { |
| 202 | IpAddr::V4(v4) => (u32::from(v4) as u128, true), |
| 203 | IpAddr::V6(v6) => (u128::from(v6), false), |
| 204 | }; |
| 205 | let width: u8 = if is_v4 { 32 } else { 128 }; |
| 206 | if prefix > width { |
| 207 | return None; |
| 208 | } |
| 209 | let mask = build_mask(prefix, is_v4); |
| 210 | Some(Self { |
| 211 | base: bits & mask, |
| 212 | mask, |
| 213 | is_v4, |
| 214 | }) |
| 215 | } |
| 216 | |
| 217 | /// Does this CIDR contain `ip`? |
| 218 | pub fn contains(&self, ip: &IpAddr) -> bool { |