use std::os::fd::{AsRawFd, FromRawFd, RawFd};
use std::path::Path;
use std::time::Duration;
use socket2::SockAddr;
use crate::driver::helpers::socket::Socket;
use crate::net::unix::{UnixListener, UnixStream};
pub struct UnixSocket {
pub(super) inner: Socket,
}
impl UnixSocket {
pub async fn close(self) -> std::io::Result<()> {
self.inner.close().await
}
pub fn new() -> std::io::Result<Self> {
let inner = Socket::new_unix(libc::SOCK_STREAM)?;
inner.set_async_flags()?;
Ok(Self { inner })
}
pub fn bind<P: AsRef<Path>>(self, path: P) -> std::io::Result<Self> {
let addr = SockAddr::unix(path)?;
self.inner.handle.bind(&addr)?;
self.inner.set_async_flags()?;
Ok(self)
}
pub async fn connect<P: AsRef<Path>>(self, path: P) -> std::io::Result<UnixStream> {
self.inner.connect(SockAddr::unix(path)?).await?;
Ok(UnixStream { inner: self.inner })
}
pub fn listen(self, backlog: u32) -> std::io::Result<UnixListener> {
self.inner.listen(backlog as i32)?;
Ok(UnixListener { inner: self.inner })
}
pub fn local_addr(&self) -> std::io::Result<std::os::unix::net::SocketAddr> {
self.inner
.handle
.local_addr()?
.as_unix()
.ok_or_else(|| std::io::Error::other("Could not get socket path"))
}
pub fn set_reuseaddr(&self, reuseaddr: bool) -> std::io::Result<()> {
self.inner.handle.set_reuse_address(reuseaddr)
}
pub fn reuseaddr(&self) -> std::io::Result<bool> {
self.inner.handle.reuse_address()
}
pub fn set_keepalive(&self, keepalive: bool) -> std::io::Result<()> {
self.inner.handle.set_keepalive(keepalive)
}
pub fn keepalive(&self) -> std::io::Result<bool> {
self.inner.handle.keepalive()
}
pub fn set_linger(&self, dur: Option<Duration>) -> std::io::Result<()> {
self.inner.handle.set_linger(dur)
}
pub fn linger(&self) -> std::io::Result<Option<Duration>> {
self.inner.handle.linger()
}
pub fn set_recv_buffer_size(&self, size: u32) -> std::io::Result<()> {
self.inner.handle.set_recv_buffer_size(size as usize)
}
pub fn recv_buffer_size(&self) -> std::io::Result<u32> {
self.inner.handle.recv_buffer_size().map(|s| s as u32)
}
pub fn set_send_buffer_size(&self, size: u32) -> std::io::Result<()> {
self.inner.handle.set_send_buffer_size(size as usize)
}
pub fn send_buffer_size(&self) -> std::io::Result<u32> {
self.inner.handle.send_buffer_size().map(|s| s as u32)
}
}
impl FromRawFd for UnixSocket {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
UnixSocket::from(unsafe { Socket::from_raw_fd(fd) })
}
}
impl AsRawFd for UnixSocket {
fn as_raw_fd(&self) -> RawFd {
self.inner.as_raw_fd()
}
}
impl From<Socket> for UnixSocket {
fn from(inner: Socket) -> Self {
Self { inner }
}
}