use core::{
fmt,
str::FromStr,
};
use std::net::IpAddr;
use super::from_str::cidr_from_str;
use crate::{
errors::*,
internal_traits::PrivCidr,
Cidr,
Family,
InetIterator,
IpCidr,
IpInet,
IpInetPair,
Ipv4Cidr,
Ipv6Cidr,
};
impl IpCidr {
pub const fn is_ipv4(&self) -> bool {
match self {
Self::V4(_) => true,
Self::V6(_) => false,
}
}
pub const fn is_ipv6(&self) -> bool {
match self {
Self::V4(_) => false,
Self::V6(_) => true,
}
}
pub const fn new(addr: IpAddr, len: u8) -> Result<Self, NetworkParseError> {
match addr {
IpAddr::V4(a) => match Ipv4Cidr::new(a, len) {
Ok(cidr) => Ok(Self::V4(cidr)),
Err(e) => Err(e),
},
IpAddr::V6(a) => match Ipv6Cidr::new(a, len) {
Ok(cidr) => Ok(Self::V6(cidr)),
Err(e) => Err(e),
},
}
}
pub const fn new_host(addr: IpAddr) -> Self {
match addr {
IpAddr::V4(a) => Self::V4(Ipv4Cidr::new_host(a)),
IpAddr::V6(a) => Self::V6(Ipv6Cidr::new_host(a)),
}
}
pub const fn iter(&self) -> InetIterator<IpAddr> {
self._range_pair().iter()
}
pub const fn first_address(&self) -> IpAddr {
match self {
Self::V4(c) => IpAddr::V4(c.first_address()),
Self::V6(c) => IpAddr::V6(c.first_address()),
}
}
pub const fn first(&self) -> IpInet {
match self {
Self::V4(c) => IpInet::V4(c.first()),
Self::V6(c) => IpInet::V6(c.first()),
}
}
pub const fn last_address(&self) -> IpAddr {
match self {
Self::V4(c) => IpAddr::V4(c.last_address()),
Self::V6(c) => IpAddr::V6(c.last_address()),
}
}
pub const fn last(&self) -> IpInet {
match self {
Self::V4(c) => IpInet::V4(c.last()),
Self::V6(c) => IpInet::V6(c.last()),
}
}
pub const fn network_length(&self) -> u8 {
match self {
Self::V4(c) => c.network_length(),
Self::V6(c) => c.network_length(),
}
}
pub const fn family(&self) -> Family {
match self {
Self::V4(_) => Family::Ipv4,
Self::V6(_) => Family::Ipv6,
}
}
pub const fn is_host_address(&self) -> bool {
match self {
Self::V4(c) => c.is_host_address(),
Self::V6(c) => c.is_host_address(),
}
}
pub const fn mask(&self) -> IpAddr {
match self {
Self::V4(c) => IpAddr::V4(c.mask()),
Self::V6(c) => IpAddr::V6(c.mask()),
}
}
pub const fn contains(&self, addr: &IpAddr) -> bool {
match self {
Self::V4(c) => match addr {
IpAddr::V4(a) => c.contains(a),
IpAddr::V6(_) => false,
},
Self::V6(c) => match addr {
IpAddr::V4(_) => false,
IpAddr::V6(a) => c.contains(a),
},
}
}
pub(crate) const fn _range_pair(&self) -> IpInetPair {
match self {
Self::V4(c) => IpInetPair::V4(c._range_pair()),
Self::V6(c) => IpInetPair::V6(c._range_pair()),
}
}
}
impl PrivCidr for IpCidr {}
impl Cidr for IpCidr {
type Address = IpAddr;
fn new(addr: IpAddr, len: u8) -> Result<Self, NetworkParseError> {
Self::new(addr, len)
}
fn new_host(addr: IpAddr) -> Self {
Self::new_host(addr)
}
fn iter(&self) -> InetIterator<IpAddr> {
self.iter()
}
fn first_address(&self) -> IpAddr {
self.first_address()
}
fn first(&self) -> IpInet {
self.first()
}
fn last_address(&self) -> IpAddr {
self.last_address()
}
fn last(&self) -> IpInet {
self.last()
}
fn network_length(&self) -> u8 {
self.network_length()
}
fn family(&self) -> Family {
self.family()
}
fn is_host_address(&self) -> bool {
self.is_host_address()
}
fn mask(&self) -> IpAddr {
self.mask()
}
fn contains(&self, addr: &IpAddr) -> bool {
self.contains(addr)
}
}
impl fmt::Display for IpCidr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::V4(c) => fmt::Display::fmt(c, f),
Self::V6(c) => fmt::Display::fmt(c, f),
}
}
}
impl FromStr for IpCidr {
type Err = NetworkParseError;
fn from_str(s: &str) -> Result<Self, NetworkParseError> {
cidr_from_str(s)
}
}
impl From<Ipv4Cidr> for IpCidr {
fn from(c: Ipv4Cidr) -> Self {
Self::V4(c)
}
}
impl From<Ipv6Cidr> for IpCidr {
fn from(c: Ipv6Cidr) -> Self {
Self::V6(c)
}
}
impl IntoIterator for IpCidr {
type IntoIter = InetIterator<IpAddr>;
type Item = IpInet;
fn into_iter(self) -> Self::IntoIter {
InetIterator::_new(self._range_pair())
}
}