address 0.20.0-rc.1

This library aids in processing network addresses.
use crate::{IPAddress, IPv4Address, IPv6Address};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

impl IPv4Address {
    //! Standard Library Conversions

    /// Converts the address to a standard library address.
    #[must_use]
    pub const fn to_std(self) -> Ipv4Addr {
        let (a, b, c, d) = self.bytes();
        Ipv4Addr::new(a, b, c, d)
    }
}

impl From<Ipv4Addr> for IPv4Address {
    fn from(std: Ipv4Addr) -> Self {
        Self::new(std.octets())
    }
}

impl From<IPv4Address> for Ipv4Addr {
    fn from(ip: IPv4Address) -> Self {
        ip.to_std()
    }
}

impl IPv6Address {
    //! Standard Library Conversions

    /// Converts the address to a standard library address.
    #[must_use]
    pub const fn to_std(self) -> Ipv6Addr {
        let segments: [u16; 8] = self.segments();
        Ipv6Addr::new(
            segments[0],
            segments[1],
            segments[2],
            segments[3],
            segments[4],
            segments[5],
            segments[6],
            segments[7],
        )
    }
}

impl From<Ipv6Addr> for IPv6Address {
    fn from(std: Ipv6Addr) -> Self {
        Self::new(std.octets())
    }
}

impl From<IPv6Address> for Ipv6Addr {
    fn from(ip: IPv6Address) -> Self {
        ip.to_std()
    }
}

impl IPAddress {
    //! Standard Library Conversions

    /// Converts the address to a standard library address.
    #[must_use]
    pub const fn to_std(self) -> IpAddr {
        match self {
            Self::V4(ip) => IpAddr::V4(ip.to_std()),
            Self::V6(ip) => IpAddr::V6(ip.to_std()),
        }
    }
}

impl From<IpAddr> for IPAddress {
    fn from(std: IpAddr) -> Self {
        match std {
            IpAddr::V4(ip) => Self::V4(IPv4Address::from(ip)),
            IpAddr::V6(ip) => Self::V6(IPv6Address::from(ip)),
        }
    }
}

impl From<IPAddress> for IpAddr {
    fn from(ip: IPAddress) -> Self {
        ip.to_std()
    }
}

#[cfg(test)]
mod tests {
    use crate::{IPAddress, IPv4Address, IPv6Address};
    use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};

    #[test]
    fn v4() {
        let test_cases: &[(IPv4Address, Ipv4Addr)] = &[(IPv4Address::LOCALHOST, Ipv4Addr::LOCALHOST)];

        for (ip, std) in test_cases {
            let result: Ipv4Addr = ip.to_std();
            assert_eq!(result, *std, "ip={:?}", ip);

            let result: Ipv4Addr = (*ip).into();
            assert_eq!(result, *std, "ip={:?}", ip);

            let result: IPv4Address = (*std).into();
            assert_eq!(result, *ip, "std={:?}", std);
        }
    }

    #[test]
    fn v6() {
        let test_cases: &[(IPv6Address, Ipv6Addr)] = &[(IPv6Address::LOCALHOST, Ipv6Addr::LOCALHOST)];

        for (ip, std) in test_cases {
            let result: Ipv6Addr = ip.to_std();
            assert_eq!(result, *std, "ip={:?}", ip);

            let result: Ipv6Addr = (*ip).into();
            assert_eq!(result, *std, "ip={:?}", ip);

            let result: IPv6Address = (*std).into();
            assert_eq!(result, *ip, "std={:?}", std);
        }
    }

    #[test]
    fn ip() {
        let test_cases: &[(IPAddress, IpAddr)] = &[
            (IPv4Address::LOCALHOST.to_ip(), IpAddr::V4(Ipv4Addr::LOCALHOST)),
            (IPv6Address::LOCALHOST.to_ip(), IpAddr::V6(Ipv6Addr::LOCALHOST)),
        ];

        for (ip, std) in test_cases {
            let result: IpAddr = ip.to_std();
            assert_eq!(result, *std, "ip={:?}", ip);

            let result: IpAddr = (*ip).into();
            assert_eq!(result, *std, "ip={:?}", ip);

            let result: IPAddress = (*std).into();
            assert_eq!(result, *ip, "std={:?}", std);
        }
    }
}