diff --git a/src/ipv4.rs b/src/ipv4.rs index c977f69..79e3eb3 100644 --- a/src/ipv4.rs +++ b/src/ipv4.rs @@ -128,6 +128,20 @@ impl Ipv4Network { Ok(net) } + /// Constructs a new `Ipv4Network` from a network address and a network mask. + /// + /// If the netmask is not valid this will return a `None`. + pub const fn with_netmask_checked(netaddr: Ipv4Addr, netmask: Ipv4Addr) -> Option { + let Some(prefix) = ipv4_mask_to_prefix_checked(netmask) else { + return None; + }; + let net = Self { + addr: netaddr, + prefix, + }; + Some(net) + } + /// Returns an iterator over `Ipv4Network`. Each call to `next` will return the next /// `Ipv4Addr` in the given network. `None` will be returned when there are no more /// addresses. diff --git a/src/ipv6.rs b/src/ipv6.rs index de07288..a82128b 100644 --- a/src/ipv6.rs +++ b/src/ipv6.rs @@ -136,6 +136,20 @@ impl Ipv6Network { Ok(net) } + /// Constructs a new `Ipv6Network` from a network address and a network mask. + /// + /// If the netmask is not valid this will return a `None`. + pub const fn with_netmask_checked(netaddr: Ipv6Addr, netmask: Ipv6Addr) -> Option { + let Some(prefix) = ipv6_mask_to_prefix_checked(netmask) else { + return None; + }; + let net = Self { + addr: netaddr, + prefix, + }; + Some(net) + } + /// Returns an iterator over `Ipv6Network`. Each call to `next` will return the next /// `Ipv6Addr` in the given network. `None` will be returned when there are no more /// addresses. diff --git a/src/lib.rs b/src/lib.rs index 1b8702a..7de75d3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -140,6 +140,30 @@ impl IpNetwork { Self::new(netaddr, prefix) } + /// Constructs a new `IpNetwork` from a network address and a network mask. + /// + /// If the netmask is not valid this will return an `None`. + pub const fn with_netmask_checked(netaddr: IpAddr, netmask: IpAddr) -> Option { + let Some(prefix) = ip_mask_to_prefix_checked(netmask) else { + return None; + }; + + match netaddr { + IpAddr::V4(address) => { + let Some(network) = Ipv4Network::new_checked(address, prefix) else { + return None; + }; + Some(IpNetwork::V4(network)) + } + IpAddr::V6(address) => { + let Some(network) = Ipv6Network::new_checked(address, prefix) else { + return None; + }; + Some(IpNetwork::V6(network)) + } + } + } + /// Returns the IP part of a given `IpNetwork` pub const fn ip(&self) -> IpAddr { match *self {