use crate::error::Error;
pub trait Transport {
fn write_all(&mut self, bytes: &[u8]) -> Result<(), Error>;
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error>;
fn flush(&mut self) -> Result<(), Error> {
Ok(())
}
}
impl<T: Transport + ?Sized> Transport for &mut T {
fn write_all(&mut self, bytes: &[u8]) -> Result<(), Error> {
(**self).write_all(bytes)
}
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
(**self).read(buf)
}
fn flush(&mut self) -> Result<(), Error> {
(**self).flush()
}
}
#[cfg(feature = "alloc")]
#[derive(Debug, Default)]
pub struct VecTransport {
pub outgoing: alloc::collections::VecDeque<u8>,
pub incoming: alloc::collections::VecDeque<u8>,
}
#[cfg(feature = "alloc")]
impl VecTransport {
pub fn new() -> Self {
Self::default()
}
pub fn feed(&mut self, bytes: &[u8]) {
self.incoming.extend(bytes.iter().copied());
}
pub fn take_outgoing(&mut self) -> alloc::vec::Vec<u8> {
let v: alloc::vec::Vec<u8> = self.outgoing.drain(..).collect();
v
}
pub fn shuffle_to(&mut self, other: &mut VecTransport) {
other.incoming.extend(self.outgoing.drain(..));
}
}
#[cfg(feature = "alloc")]
impl Transport for VecTransport {
fn write_all(&mut self, bytes: &[u8]) -> Result<(), Error> {
self.outgoing.extend(bytes.iter().copied());
Ok(())
}
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
let n = buf.len().min(self.incoming.len());
for slot in buf.iter_mut().take(n) {
*slot = self.incoming.pop_front().unwrap();
}
Ok(n)
}
}
#[cfg(feature = "embedded-io")]
#[cfg_attr(docsrs, doc(cfg(feature = "embedded-io")))]
pub struct EmbeddedIoTransport<T> {
pub inner: T,
}
#[cfg(feature = "embedded-io")]
impl<T> EmbeddedIoTransport<T> {
pub fn new(inner: T) -> Self {
Self { inner }
}
pub fn into_inner(self) -> T {
self.inner
}
}
#[cfg(feature = "embedded-io")]
impl<T> Transport for EmbeddedIoTransport<T>
where
T: embedded_io::Read + embedded_io::Write,
{
fn write_all(&mut self, bytes: &[u8]) -> Result<(), Error> {
embedded_io::Write::write_all(&mut self.inner, bytes)
.map_err(|_| Error::Io("embedded-io write failed"))
}
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
embedded_io::Read::read(&mut self.inner, buf)
.map_err(|_| Error::Io("embedded-io read failed"))
}
fn flush(&mut self) -> Result<(), Error> {
embedded_io::Write::flush(&mut self.inner)
.map_err(|_| Error::Io("embedded-io flush failed"))
}
}