#[cfg(not(debug_assertions))]
use std::sync::LazyLock;
use std::{fmt::Display, net::SocketAddr};
#[cfg(not(debug_assertions))]
static SECRET: LazyLock<[u8; 32]> = LazyLock::new(|| super::utils::get_random_bytes());
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
pub struct IpDisplay {
addr: SocketAddr,
}
impl From<SocketAddr> for IpDisplay {
fn from(value: SocketAddr) -> Self {
IpDisplay { addr: value }
}
}
impl Display for IpDisplay {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if cfg!(debug_assertions) {
self.addr.fmt(f)
} else {
#[cfg(debug_assertions)]
unreachable!();
#[cfg(not(debug_assertions))]
{
use std::net::IpAddr;
let mut hasher = blake3::Hasher::new_keyed(&*SECRET);
hasher.update(&[self.addr.is_ipv4() as u8]);
match self.addr.ip().to_canonical() {
IpAddr::V4(addr) => hasher.update(&addr.octets()),
IpAddr::V6(addr) => hasher.update(&addr.octets()),
};
let hex = hasher.finalize().to_hex();
write!(f, "{}:{}", &hex[..10], self.addr.port())
}
}
}
}
impl std::fmt::Debug for IpDisplay {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self)
}
}