use alloc::boxed::Box;
use core::future::Future;
use core::pin::Pin;
use embedded_io::Error as _;
use crate::error::{Error, Result};
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
trait DynWrite {
fn dyn_write_all<'a>(&'a mut self, buf: &'a [u8]) -> BoxFuture<'a, Result<()>>;
fn dyn_flush<'a>(&'a mut self) -> BoxFuture<'a, Result<()>>;
}
impl<W> DynWrite for W
where
W: embedded_io_async::Write + ?Sized,
{
fn dyn_write_all<'a>(&'a mut self, buf: &'a [u8]) -> BoxFuture<'a, Result<()>> {
Box::pin(async move {
embedded_io_async::Write::write_all(self, buf)
.await
.map_err(|e| Error::Io(e.kind()))
})
}
fn dyn_flush<'a>(&'a mut self) -> BoxFuture<'a, Result<()>> {
Box::pin(async move {
embedded_io_async::Write::flush(self)
.await
.map_err(|e| Error::Io(e.kind()))
})
}
}
pub struct Io<'a> {
w: &'a mut dyn DynWrite,
}
impl<'a> Io<'a> {
pub(crate) fn new<W: embedded_io_async::Write>(w: &'a mut W) -> Self {
Io { w }
}
pub async fn print(&mut self, s: &str) -> Result<()> {
self.w.dyn_write_all(s.as_bytes()).await?;
self.w.dyn_flush().await
}
pub async fn println(&mut self, s: &str) -> Result<()> {
self.w.dyn_write_all(s.as_bytes()).await?;
self.w.dyn_write_all(b"\r\n").await?;
self.w.dyn_flush().await
}
pub async fn write_all(&mut self, buf: &[u8]) -> Result<()> {
self.w.dyn_write_all(buf).await?;
self.w.dyn_flush().await
}
pub async fn flush(&mut self) -> Result<()> {
self.w.dyn_flush().await
}
}
impl embedded_io::ErrorType for Io<'_> {
type Error = Error;
}
impl embedded_io_async::Write for Io<'_> {
async fn write(&mut self, buf: &[u8]) -> core::result::Result<usize, Error> {
self.w.dyn_write_all(buf).await?;
Ok(buf.len())
}
async fn flush(&mut self) -> core::result::Result<(), Error> {
self.w.dyn_flush().await
}
}