use crate::{
Channel,
errors::{ChannelError, ChannelResult},
};
use async_channel::{Receiver, Sender, unbounded};
use async_trait::async_trait;
use std::io::Result;
#[derive(Debug, Clone)]
pub struct BidirectionalChannel {
pub client: NativeChannel,
pub host: NativeChannel,
}
impl BidirectionalChannel {
pub fn new() -> Result<Self> {
let (bw, ar) = unbounded();
let (aw, br) = unbounded();
Ok(Self {
client: NativeChannel { read: ar, write: aw },
host: NativeChannel { read: br, write: bw },
})
}
}
#[derive(Debug, Clone)]
pub struct NativeChannel {
pub(crate) read: Receiver<Vec<u8>>,
pub(crate) write: Sender<Vec<u8>>,
}
#[async_trait]
impl Channel for NativeChannel {
async fn read(&self, buf: &mut [u8]) -> ChannelResult<usize> {
let data = self.read.recv().await.map_err(|_| ChannelError::Closed)?;
let len = data.len().min(buf.len());
buf[..len].copy_from_slice(&data[..len]);
Ok(len)
}
async fn read_exact(&self, buf: &mut [u8]) -> ChannelResult<usize> {
let data = self.read.recv().await.map_err(|_| ChannelError::Closed)?;
buf[..].copy_from_slice(&data[..]);
Ok(buf.len())
}
async fn write(&self, buf: &[u8]) -> ChannelResult<usize> {
self.write.send(buf.to_vec()).await.map_err(|_| ChannelError::Closed)?;
Ok(buf.len())
}
}