use crate::*;
#[allow(dead_code)]
pub(crate) struct IpcRead {
config: Arc<Config>,
read_half: tokio::io::ReadHalf<tokio::net::UnixStream>,
}
impl tokio::io::AsyncRead for IpcRead {
fn poll_read(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
buf: &mut [u8],
) -> std::task::Poll<tokio::io::Result<usize>> {
let r = &mut self.read_half;
tokio::pin!(r);
tokio::io::AsyncRead::poll_read(r, cx, buf)
}
}
#[allow(dead_code)]
pub(crate) struct IpcWrite {
config: Arc<Config>,
write_half: tokio::io::WriteHalf<tokio::net::UnixStream>,
}
impl tokio::io::AsyncWrite for IpcWrite {
fn poll_write(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
buf: &[u8],
) -> std::task::Poll<tokio::io::Result<usize>> {
let r = &mut self.write_half;
tokio::pin!(r);
tokio::io::AsyncWrite::poll_write(r, cx, buf)
}
fn poll_flush(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<tokio::io::Result<()>> {
let r = &mut self.write_half;
tokio::pin!(r);
tokio::io::AsyncWrite::poll_flush(r, cx)
}
fn poll_shutdown(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<tokio::io::Result<()>> {
let r = &mut self.write_half;
tokio::pin!(r);
tokio::io::AsyncWrite::poll_shutdown(r, cx)
}
}
pub(crate) async fn ipc_connect(
config: Arc<Config>,
) -> LairResult<(IpcRead, IpcWrite)> {
let socket = tokio::net::UnixStream::connect(config.get_socket_path())
.await
.map_err(|e| {
LairError::IpcClientConnectError(
config.get_socket_path().to_string_lossy().to_string(),
e.into(),
)
})?;
let (read_half, write_half) = tokio::io::split(socket);
Ok((
IpcRead {
config: config.clone(),
read_half,
},
IpcWrite { config, write_half },
))
}
#[allow(dead_code)]
pub(crate) struct IpcServer {
config: Arc<Config>,
socket: tokio::net::UnixListener,
}
impl IpcServer {
pub fn bind(config: Arc<Config>) -> LairResult<Self> {
let _ = std::fs::remove_file(config.get_socket_path());
let socket = tokio::net::UnixListener::bind(config.get_socket_path())
.map_err(LairError::other)?;
Ok(Self { config, socket })
}
pub async fn accept(&mut self) -> LairResult<(IpcRead, IpcWrite)> {
let (con, _) = self.socket.accept().await.map_err(LairError::other)?;
let (read_half, write_half) = tokio::io::split(con);
Ok((
IpcRead {
config: self.config.clone(),
read_half,
},
IpcWrite {
config: self.config.clone(),
write_half,
},
))
}
}