1use crate::error::Error;
5
6pub trait Transport {
8 fn write_all(&mut self, bytes: &[u8]) -> Result<(), Error>;
11
12 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error>;
18
19 fn flush(&mut self) -> Result<(), Error> {
21 Ok(())
22 }
23}
24
25impl<T: Transport + ?Sized> Transport for &mut T {
26 fn write_all(&mut self, bytes: &[u8]) -> Result<(), Error> {
27 (**self).write_all(bytes)
28 }
29 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
30 (**self).read(buf)
31 }
32 fn flush(&mut self) -> Result<(), Error> {
33 (**self).flush()
34 }
35}
36
37#[cfg(feature = "alloc")]
39#[derive(Debug, Default)]
40pub struct VecTransport {
41 pub outgoing: alloc::collections::VecDeque<u8>,
44 pub incoming: alloc::collections::VecDeque<u8>,
46}
47
48#[cfg(feature = "alloc")]
49impl VecTransport {
50 pub fn new() -> Self {
52 Self::default()
53 }
54
55 pub fn feed(&mut self, bytes: &[u8]) {
57 self.incoming.extend(bytes.iter().copied());
58 }
59
60 pub fn take_outgoing(&mut self) -> alloc::vec::Vec<u8> {
62 let v: alloc::vec::Vec<u8> = self.outgoing.drain(..).collect();
63 v
64 }
65
66 pub fn shuffle_to(&mut self, other: &mut VecTransport) {
70 other.incoming.extend(self.outgoing.drain(..));
71 }
72}
73
74#[cfg(feature = "alloc")]
75impl Transport for VecTransport {
76 fn write_all(&mut self, bytes: &[u8]) -> Result<(), Error> {
77 self.outgoing.extend(bytes.iter().copied());
78 Ok(())
79 }
80
81 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
82 let n = buf.len().min(self.incoming.len());
83 for slot in buf.iter_mut().take(n) {
84 *slot = self.incoming.pop_front().unwrap();
85 }
86 Ok(n)
87 }
88}
89
90#[cfg(feature = "embedded-io")]
96#[cfg_attr(docsrs, doc(cfg(feature = "embedded-io")))]
97pub struct EmbeddedIoTransport<T> {
98 pub inner: T,
100}
101
102#[cfg(feature = "embedded-io")]
103impl<T> EmbeddedIoTransport<T> {
104 pub fn new(inner: T) -> Self {
106 Self { inner }
107 }
108
109 pub fn into_inner(self) -> T {
111 self.inner
112 }
113}
114
115#[cfg(feature = "embedded-io")]
116impl<T> Transport for EmbeddedIoTransport<T>
117where
118 T: embedded_io::Read + embedded_io::Write,
119{
120 fn write_all(&mut self, bytes: &[u8]) -> Result<(), Error> {
121 embedded_io::Write::write_all(&mut self.inner, bytes)
122 .map_err(|_| Error::Io("embedded-io write failed"))
123 }
124
125 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
126 embedded_io::Read::read(&mut self.inner, buf)
127 .map_err(|_| Error::Io("embedded-io read failed"))
128 }
129
130 fn flush(&mut self) -> Result<(), Error> {
131 embedded_io::Write::flush(&mut self.inner)
132 .map_err(|_| Error::Io("embedded-io flush failed"))
133 }
134}