use crate::{
IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6, SocketAddressV4, SocketAddressV6,
};
use core::fmt;
use core::hash;
use core::iter::Iterator;
use core::option;
pub enum SocketAddr<SA4: SocketAddressV4, SA6: SocketAddressV6> {
V4(SocketAddrV4<SA4>),
V6(SocketAddrV6<SA6>),
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> SocketAddr<SA4, SA6> {
pub fn new(ip: IpAddr<SA4::IpAddress, SA6::IpAddress>, port: u16) -> SocketAddr<SA4, SA6> {
match ip {
IpAddr::V4(a) => SocketAddr::V4(SocketAddrV4::new(a, port)),
IpAddr::V6(a) => SocketAddr::V6(SocketAddrV6::new(a, port, 0, 0)),
}
}
pub fn ip(&self) -> IpAddr<SA4::IpAddress, SA6::IpAddress> {
match *self {
SocketAddr::V4(ref a) => IpAddr::V4(*a.ip()),
SocketAddr::V6(ref a) => IpAddr::V6(*a.ip()),
}
}
pub fn set_ip(&mut self, new_ip: IpAddr<SA4::IpAddress, SA6::IpAddress>) {
match (self, new_ip) {
(&mut SocketAddr::V4(ref mut a), IpAddr::V4(new_ip)) => a.set_ip(new_ip),
(&mut SocketAddr::V6(ref mut a), IpAddr::V6(new_ip)) => a.set_ip(new_ip),
(self_, new_ip) => *self_ = Self::new(new_ip, self_.port()),
}
}
pub fn port(&self) -> u16 {
match *self {
SocketAddr::V4(ref a) => a.port(),
SocketAddr::V6(ref a) => a.port(),
}
}
pub fn set_port(&mut self, new_port: u16) {
match *self {
SocketAddr::V4(ref mut a) => a.set_port(new_port),
SocketAddr::V6(ref mut a) => a.set_port(new_port),
}
}
pub fn is_ipv4(&self) -> bool {
matches!(*self, SocketAddr::V4(_))
}
pub fn is_ipv6(&self) -> bool {
matches!(*self, SocketAddr::V6(_))
}
}
impl<
SA4: SocketAddressV4,
SA6: SocketAddressV6,
I: Into<IpAddr<SA4::IpAddress, SA6::IpAddress>>,
> From<(I, u16)> for SocketAddr<SA4, SA6>
{
fn from(pieces: (I, u16)) -> SocketAddr<SA4, SA6> {
SocketAddr::new(pieces.0.into(), pieces.1)
}
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> From<SocketAddrV4<SA4>> for SocketAddr<SA4, SA6> {
fn from(sock4: SocketAddrV4<SA4>) -> SocketAddr<SA4, SA6> {
SocketAddr::V4(sock4)
}
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> From<SocketAddrV6<SA6>> for SocketAddr<SA4, SA6> {
fn from(sock6: SocketAddrV6<SA6>) -> SocketAddr<SA4, SA6> {
SocketAddr::V6(sock6)
}
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> Clone for SocketAddr<SA4, SA6> {
fn clone(&self) -> Self {
match self {
SocketAddr::V4(a) => SocketAddr::V4(a.clone()),
SocketAddr::V6(a) => SocketAddr::V6(a.clone()),
}
}
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> Copy for SocketAddr<SA4, SA6> {}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> fmt::Display for SocketAddr<SA4, SA6> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}", self.ip(), self.port())
}
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> fmt::Debug for SocketAddr<SA4, SA6> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, fmt)
}
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> Eq for SocketAddr<SA4, SA6> {}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> PartialEq for SocketAddr<SA4, SA6> {
fn eq(&self, other: &SocketAddr<SA4, SA6>) -> bool {
match (self, other) {
(SocketAddr::V4(s), SocketAddr::V4(o)) => s == o,
(SocketAddr::V6(s), SocketAddr::V6(o)) => s == o,
_ => false,
}
}
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> hash::Hash for SocketAddr<SA4, SA6> {
fn hash<H: hash::Hasher>(&self, s: &mut H) {
let ip = self.ip();
let port = self.port();
(ip, port).hash(s)
}
}
pub enum ToSocketAddrError {}
pub trait ToSocketAddrs<SA4: SocketAddressV4, SA6: SocketAddressV6> {
type Iter: Iterator<Item = SocketAddr<SA4, SA6>>;
fn to_socket_addrs(&self) -> Result<Self::Iter, ToSocketAddrError>;
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> ToSocketAddrs<SA4, SA6> for SocketAddr<SA4, SA6> {
type Iter = option::IntoIter<SocketAddr<SA4, SA6>>;
fn to_socket_addrs(&self) -> Result<option::IntoIter<SocketAddr<SA4, SA6>>, ToSocketAddrError> {
Ok(Some(*self).into_iter())
}
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> ToSocketAddrs<SA4, SA6> for SocketAddrV4<SA4> {
type Iter = option::IntoIter<SocketAddr<SA4, SA6>>;
fn to_socket_addrs(&self) -> Result<option::IntoIter<SocketAddr<SA4, SA6>>, ToSocketAddrError> {
SocketAddr::V4(*self).to_socket_addrs()
}
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> ToSocketAddrs<SA4, SA6> for SocketAddrV6<SA6> {
type Iter = option::IntoIter<SocketAddr<SA4, SA6>>;
fn to_socket_addrs(&self) -> Result<option::IntoIter<SocketAddr<SA4, SA6>>, ToSocketAddrError> {
SocketAddr::V6(*self).to_socket_addrs()
}
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> ToSocketAddrs<SA4, SA6>
for (IpAddr<SA4::IpAddress, SA6::IpAddress>, u16)
{
type Iter = option::IntoIter<SocketAddr<SA4, SA6>>;
fn to_socket_addrs(&self) -> Result<option::IntoIter<SocketAddr<SA4, SA6>>, ToSocketAddrError> {
let (ip, port) = *self;
match ip {
IpAddr::V4(ref a) => (*a, port).to_socket_addrs(),
IpAddr::V6(ref a) => (*a, port).to_socket_addrs(),
}
}
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> ToSocketAddrs<SA4, SA6>
for (Ipv4Addr<SA4::IpAddress>, u16)
{
type Iter = option::IntoIter<SocketAddr<SA4, SA6>>;
fn to_socket_addrs(&self) -> Result<option::IntoIter<SocketAddr<SA4, SA6>>, ToSocketAddrError> {
let (ip, port) = *self;
SocketAddrV4::new(ip, port).to_socket_addrs()
}
}
impl<SA4: SocketAddressV4, SA6: SocketAddressV6> ToSocketAddrs<SA4, SA6>
for (Ipv6Addr<SA6::IpAddress>, u16)
{
type Iter = option::IntoIter<SocketAddr<SA4, SA6>>;
fn to_socket_addrs(&self) -> Result<option::IntoIter<SocketAddr<SA4, SA6>>, ToSocketAddrError> {
let (ip, port) = *self;
SocketAddrV6::new(ip, port, 0, 0).to_socket_addrs()
}
}