use super::interprocess::name_onto;
use crate::message::Message;
use crate::{Error, Result};
use async_trait::async_trait;
use futures_io::{AsyncRead, AsyncWrite};
use interprocess::local_socket::tokio::{LocalSocketListener, LocalSocketStream};
use serde::de::DeserializeOwned;
use serde::Serialize;
pub struct Listener {
internal: Box<dyn ListenerImpl>,
closed: bool,
}
impl Listener {
pub const fn new(internal: Box<dyn ListenerImpl>) -> Self {
Self {
internal,
closed: false,
}
}
pub fn listen_as_socket<S>(name: S, global: bool) -> Result<Self>
where
S: AsRef<str>,
{
let bound = name_onto!(LocalSocketListener::bind; name, global)?;
Ok(Self::new(Box::new(bound)))
}
pub async fn accept(&mut self) -> Result<Connection> {
if self.closed {
return Err(Error::Closed(false));
}
self.internal.accept().await
}
pub async fn close(&mut self) -> Result<()> {
if self.closed {
return Err(Error::Closed(false));
}
self.closed = true; self.internal.close().await
}
pub fn is_closed(&self) -> bool {
self.closed
}
}
pub struct Connection {
internal: Box<dyn ConnectionImpl>,
closed: bool,
}
impl Connection {
pub const fn new(internal: Box<dyn ConnectionImpl>) -> Self {
Self {
internal,
closed: false,
}
}
pub async fn connect_to_socket<S>(name: S, global: bool) -> Result<Self>
where
S: AsRef<str>,
{
let bound = name_onto!(await LocalSocketStream::connect; name, global)?;
Ok(Self::new(Box::new(bound)))
}
async fn _send<T>(&mut self, message: Message<T>) -> Result<()>
where
T: Serialize,
{
message.write_to_async(&mut self.internal).await
}
async fn _receive<T>(&mut self) -> Result<Message<T>>
where
T: DeserializeOwned,
{
Message::<T>::read_from_async(&mut self.internal).await
}
pub async fn send<T>(&mut self, message_data: T) -> Result<()>
where
T: Serialize,
{
if self.closed {
return Err(Error::Closed(false));
}
let message = Message::Data(message_data);
self._send(message).await
}
pub async fn receive<T>(&mut self) -> Result<T>
where
T: DeserializeOwned,
{
if self.closed {
return Err(Error::Closed(false));
}
let message = self._receive().await?;
match message {
Message::ClosingConnection => {
self._close().await;
Err(Error::Closed(true))
}
Message::Data(data) => Ok(data),
}
}
pub async fn send_and_receive<A, B>(&mut self, data: &A) -> Result<B>
where
A: Serialize,
B: DeserializeOwned,
{
self.send(data).await?;
self.receive().await
}
async fn _close(&mut self) {
self.internal.close().await;
self.closed = true;
}
pub async fn close(&mut self) {
if self.closed {
return;
}
let _ = self._send::<()>(Message::ClosingConnection);
self._close().await;
}
pub fn is_closed(&self) -> bool {
self.closed
}
}
#[async_trait]
pub trait ListenerImpl: Send + Unpin {
async fn accept(&mut self) -> Result<Connection>;
async fn close(&mut self) -> Result<()>;
}
#[async_trait]
impl ListenerImpl for LocalSocketListener {
async fn accept(&mut self) -> Result<Connection> {
Ok(Connection::from(LocalSocketListener::accept(self).await?))
}
async fn close(&mut self) -> Result<()> {
Ok(())
}
}
#[async_trait]
pub trait ConnectionImpl: AsyncRead + AsyncWrite + Send + Unpin {
async fn close(&mut self);
}
#[async_trait]
impl ConnectionImpl for LocalSocketStream {
async fn close(&mut self) {
}
}
impl From<LocalSocketStream> for Connection {
fn from(value: LocalSocketStream) -> Self {
Connection::new(Box::new(value))
}
}