use std::{
fmt,
net::{Ipv4Addr, SocketAddr},
ops::{Deref, DerefMut},
str::FromStr,
};
#[cfg(any(test, feature = "proptest-impl"))]
use proptest_derive::Arbitrary;
#[derive(
Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
)]
#[serde(transparent)]
#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
pub struct PeerSocketAddr(SocketAddr);
impl fmt::Debug for PeerSocketAddr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl fmt::Display for PeerSocketAddr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let ip_version = if self.is_ipv4() { "v4" } else { "v6" };
f.pad(&format!("{}redacted:{}", ip_version, self.port()))
}
}
impl FromStr for PeerSocketAddr {
type Err = <SocketAddr as FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(s.parse()?))
}
}
impl<S> From<S> for PeerSocketAddr
where
S: Into<SocketAddr>,
{
fn from(value: S) -> Self {
Self(value.into())
}
}
impl Deref for PeerSocketAddr {
type Target = SocketAddr;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for PeerSocketAddr {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl PeerSocketAddr {
pub fn unspecified() -> Self {
Self(SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 0))
}
pub fn remove_socket_addr_privacy(&self) -> SocketAddr {
**self
}
}