fn default_ip() -> String {
core::net::IpAddr::V4(core::net::Ipv4Addr::LOCALHOST).to_string()
}
fn default_port() -> u16 {
crate::DEFAULT_PORT
}
#[derive(
Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, serde::Deserialize, serde::Serialize,
)]
#[serde(default)]
pub struct NetAddr {
#[serde(default = "default_ip")]
pub host: String,
#[serde(default = "default_port")]
pub port: u16,
}
impl NetAddr {
pub fn new(host: impl ToString, port: u16) -> Self {
Self {
host: host.to_string(),
port,
}
}
pub fn from_socket_addr(addr: core::net::SocketAddr) -> Self {
Self {
host: addr.ip().to_string(),
port: addr.port(),
}
}
pub fn localhost(port: u16) -> Self {
Self::new(default_ip(), port)
}
pub fn as_socket_addr(&self) -> core::net::SocketAddr {
self.to_string().parse().unwrap()
}
pub async fn bind(&self) -> std::io::Result<tokio::net::TcpListener> {
tokio::net::TcpListener::bind(&self.as_socket_addr()).await
}
pub fn ip(&self) -> core::net::IpAddr {
self.as_socket_addr().ip()
}
pub fn port(&self) -> u16 {
self.port
}
get!(host: String);
setwith!(host: String, port: u16);
}
impl Default for NetAddr {
fn default() -> Self {
Self {
host: crate::DEFAULT_HOST.to_string(),
port: crate::DEFAULT_PORT,
}
}
}
impl core::fmt::Display for NetAddr {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "{host}:{port}", host = self.host, port = self.port)
}
}
impl core::str::FromStr for NetAddr {
type Err = Box<dyn core::error::Error>;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut parts = s.split(':');
let host: core::net::IpAddr = parts.next().unwrap().parse()?;
let port = parts.next().unwrap().parse()?;
Ok(Self {
host: host.to_string(),
port,
})
}
}
impl From<core::net::SocketAddr> for NetAddr {
fn from(addr: core::net::SocketAddr) -> Self {
Self::from_socket_addr(addr)
}
}