use std::sync::Arc;
use async_trait::async_trait;
use serde_json::Value;
use tokio::sync::Mutex;
use crate::errors::Result;
pub mod subprocess_cli;
pub type TransportSplitResult = Result<(
Box<dyn TransportReader>,
Box<dyn TransportWriter>,
Box<dyn TransportCloseHandle>,
)>;
#[async_trait]
pub trait TransportReader: Send {
async fn read_next_message(&mut self) -> Result<Option<Value>>;
}
#[async_trait]
pub trait TransportWriter: Send {
async fn write(&mut self, data: &str) -> Result<()>;
async fn end_input(&mut self) -> Result<()>;
}
#[async_trait]
pub trait Transport: Send {
async fn connect(&mut self) -> Result<()>;
async fn write(&mut self, data: &str) -> Result<()>;
async fn end_input(&mut self) -> Result<()>;
async fn read_next_message(&mut self) -> Result<Option<Value>>;
async fn close(&mut self) -> Result<()>;
fn is_ready(&self) -> bool;
fn into_split(self: Box<Self>) -> TransportSplitResult;
}
#[async_trait]
pub trait TransportCloseHandle: Send + Sync {
async fn close(&self) -> Result<()>;
}
pub trait TransportFactory: Send + Sync {
fn create_transport(&self) -> Result<Box<dyn Transport>>;
}
pub fn split_with_adapter(transport: Box<dyn Transport>) -> TransportSplitResult {
let adapter = SplitAdapter::new(transport);
Ok((
Box::new(adapter.reader()),
Box::new(adapter.writer()),
Box::new(adapter),
))
}
pub struct SplitAdapter {
inner: Arc<Mutex<Box<dyn Transport>>>,
}
impl SplitAdapter {
pub fn new(transport: Box<dyn Transport>) -> Self {
Self {
inner: Arc::new(Mutex::new(transport)),
}
}
pub fn reader(&self) -> SplitAdapterReader {
SplitAdapterReader {
inner: self.inner.clone(),
}
}
pub fn writer(&self) -> SplitAdapterWriter {
SplitAdapterWriter {
inner: self.inner.clone(),
}
}
}
#[async_trait]
impl TransportCloseHandle for SplitAdapter {
async fn close(&self) -> Result<()> {
self.inner.lock().await.close().await
}
}
pub struct SplitAdapterReader {
inner: Arc<Mutex<Box<dyn Transport>>>,
}
#[async_trait]
impl TransportReader for SplitAdapterReader {
async fn read_next_message(&mut self) -> Result<Option<Value>> {
self.inner.lock().await.read_next_message().await
}
}
pub struct SplitAdapterWriter {
inner: Arc<Mutex<Box<dyn Transport>>>,
}
#[async_trait]
impl TransportWriter for SplitAdapterWriter {
async fn write(&mut self, data: &str) -> Result<()> {
self.inner.lock().await.write(data).await
}
async fn end_input(&mut self) -> Result<()> {
self.inner.lock().await.end_input().await
}
}