#![doc = include_str!("../README.md")]
#![allow(clippy::multiple_inherent_impl)]
#[cfg(not(unix))]
mod default;
#[cfg(unix)]
mod unix;
use std::io;
use socket2::SockRef;
use uni_addr::{UniAddr, UniAddrInner};
#[cfg(not(unix))]
pub use self::default::{OwnedReadHalf, OwnedWriteHalf, UniStream};
#[cfg(unix)]
pub use self::unix::{OwnedReadHalf, OwnedWriteHalf, UniStream};
#[derive(Debug)]
pub enum UniListener {
Tcp(tokio::net::TcpListener),
#[cfg(unix)]
Unix(tokio::net::UnixListener),
}
impl UniListener {
pub async fn bind(addr: &UniAddr) -> io::Result<Self> {
match addr.as_inner() {
UniAddrInner::Inet(addr) => tokio::net::TcpListener::bind(addr).await.map(Self::Tcp),
#[cfg(unix)]
UniAddrInner::Unix(addr) => {
tokio::net::UnixListener::bind(addr.to_os_string()).map(Self::Unix)
}
UniAddrInner::Host(addr) => tokio::net::TcpListener::bind(&**addr).await.map(Self::Tcp),
_ => Err(io::Error::new(
io::ErrorKind::Other,
"unsupported address type",
)),
}
}
pub fn local_addr(&self) -> io::Result<UniAddr> {
match self {
UniListener::Tcp(listener) => listener.local_addr().map(UniAddr::from),
#[cfg(unix)]
UniListener::Unix(listener) => listener.local_addr().map(UniAddr::from),
}
}
pub fn as_socket_ref(&self) -> SockRef<'_> {
match self {
UniListener::Tcp(listener) => listener.into(),
#[cfg(unix)]
UniListener::Unix(listener) => listener.into(),
}
}
pub async fn accept(&self) -> io::Result<(UniStream, UniAddr)> {
match self {
UniListener::Tcp(listener) => {
let (stream, addr) = listener.accept().await?;
Ok((UniStream::try_from(stream)?, UniAddr::from(addr)))
}
#[cfg(unix)]
UniListener::Unix(listener) => {
let (stream, addr) = listener.accept().await?;
Ok((UniStream::try_from(stream)?, UniAddr::from(addr)))
}
}
}
}