use crate::{Host, HostRef, IPAddress, IPv4Address, IPv6Address, SocketAddressV6};
impl IPv6Address {
pub const fn to_v4(self) -> Result<IPv4Address, Self> {
match self.address() {
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d] => Ok(IPv4Address::new([a, b, c, d])),
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d] => {
Ok(IPv4Address::new([a, b, c, d]))
}
_ => Err(self),
}
}
pub const fn to_v4_mapped(self) -> Result<IPv4Address, Self> {
match self.address() {
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d] => {
Ok(IPv4Address::new([a, b, c, d]))
}
_ => Err(self),
}
}
pub const fn to_ip(self) -> IPAddress {
IPAddress::V6(self)
}
pub const fn to_socket(self, port: u16) -> SocketAddressV6 {
SocketAddressV6::new(self, port)
}
pub const fn to_host(self) -> Host {
Host::IPAddress(self.to_ip())
}
pub const fn to_host_ref(self) -> HostRef<'static> {
HostRef::IPAddress(self.to_ip())
}
}
impl TryFrom<IPAddress> for IPv6Address {
type Error = IPAddress;
fn try_from(ip: IPAddress) -> Result<Self, Self::Error> {
ip.to_v6()
}
}
#[cfg(test)]
mod tests {
use crate::{Host, HostRef, IPAddress, IPv4Address, IPv6Address, SocketAddressV6};
#[test]
fn v6_to_v4() {
let test_cases: &[(IPv6Address, Result<IPv4Address, IPv6Address>)] = &[
(
IPv6Address::from([0, 0, 0, 0, 0, 0, 0x7F00, 1]),
Ok(IPv4Address::LOCALHOST),
),
(
IPv6Address::from([0, 0, 0, 0, 0, 0xFFFF, 0x7F00, 1]),
Ok(IPv4Address::LOCALHOST),
),
(
IPv6Address::from([1, 0, 0, 0, 0, 0, 0, 0]),
Err(IPv6Address::from([1, 0, 0, 0, 0, 0, 0, 0])),
),
(
IPv6Address::from([0, 0, 0, 0, 0, 1, 0, 0]),
Err(IPv6Address::from([0, 0, 0, 0, 0, 1, 0, 0])),
),
];
for (ip, expected) in test_cases {
let result: Result<IPv4Address, IPv6Address> = ip.to_v4();
assert_eq!(result, *expected, "ip={}", ip);
}
let ip: IPv6Address = IPv6Address::from([0, 0, 0, 0, 0, 0xFFFF, 0x7F00, 1]);
let result: Result<IPv4Address, IPv6Address> = ip.to_v4_mapped();
let expected: Result<IPv4Address, IPv6Address> = Ok(IPv4Address::LOCALHOST);
assert_eq!(result, expected);
let ip: IPv6Address = IPv6Address::from([0, 0, 0, 0, 0, 0, 0x7F00, 1]);
let result: Result<IPv4Address, IPv6Address> = ip.to_v4_mapped();
let expected: Result<IPv4Address, IPv6Address> = Err(ip);
assert_eq!(result, expected);
}
#[test]
fn v6_to_ip() {
let ip: IPv6Address = IPv6Address::LOCALHOST;
let result: IPAddress = ip.to_ip();
let expected: IPAddress = IPAddress::V6(IPv6Address::LOCALHOST);
assert_eq!(result, expected);
}
#[test]
fn v6_to_socket() {
let ip: IPv6Address = IPv6Address::LOCALHOST;
let result: SocketAddressV6 = ip.to_socket(80);
let expected: SocketAddressV6 = SocketAddressV6::new(IPv6Address::LOCALHOST, 80);
assert_eq!(result, expected);
}
#[test]
fn v6_to_host() {
let ip: IPv6Address = IPv6Address::LOCALHOST;
let result: Host = ip.to_host();
let expected: Host = Host::IPAddress(IPAddress::V6(IPv6Address::LOCALHOST));
assert_eq!(result, expected);
let result: HostRef = ip.to_host_ref();
let expected: HostRef = HostRef::IPAddress(IPAddress::V6(IPv6Address::LOCALHOST));
assert_eq!(result, expected);
}
#[test]
fn v6_try_from() {
let ip: IPAddress = IPv6Address::LOCALHOST.to_ip();
assert_eq!(IPv6Address::try_from(ip), Ok(IPv6Address::LOCALHOST));
let ip: IPAddress = IPv4Address::LOCALHOST.to_ip();
assert_eq!(IPv6Address::try_from(ip), Err(ip));
}
}