1use alloc::boxed::Box;
2use core::future::Future;
3use core::pin::Pin;
4
5use embedded_io::Error as _;
6
7use crate::error::{Error, Result};
8
9pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
15
16trait DynWrite {
19 fn dyn_write_all<'a>(&'a mut self, buf: &'a [u8]) -> BoxFuture<'a, Result<()>>;
20 fn dyn_flush<'a>(&'a mut self) -> BoxFuture<'a, Result<()>>;
21}
22
23impl<W> DynWrite for W
24where
25 W: embedded_io_async::Write + ?Sized,
26{
27 fn dyn_write_all<'a>(&'a mut self, buf: &'a [u8]) -> BoxFuture<'a, Result<()>> {
28 Box::pin(async move {
29 embedded_io_async::Write::write_all(self, buf)
30 .await
31 .map_err(|e| Error::Io(e.kind()))
32 })
33 }
34
35 fn dyn_flush<'a>(&'a mut self) -> BoxFuture<'a, Result<()>> {
36 Box::pin(async move {
37 embedded_io_async::Write::flush(self)
38 .await
39 .map_err(|e| Error::Io(e.kind()))
40 })
41 }
42}
43
44pub struct Io<'a> {
52 w: &'a mut dyn DynWrite,
53}
54
55impl<'a> Io<'a> {
56 pub(crate) fn new<W: embedded_io_async::Write>(w: &'a mut W) -> Self {
57 Io { w }
58 }
59
60 pub async fn print(&mut self, s: &str) -> Result<()> {
62 self.w.dyn_write_all(s.as_bytes()).await?;
63 self.w.dyn_flush().await
64 }
65
66 pub async fn println(&mut self, s: &str) -> Result<()> {
68 self.w.dyn_write_all(s.as_bytes()).await?;
69 self.w.dyn_write_all(b"\r\n").await?;
70 self.w.dyn_flush().await
71 }
72
73 pub async fn write_all(&mut self, buf: &[u8]) -> Result<()> {
75 self.w.dyn_write_all(buf).await?;
76 self.w.dyn_flush().await
77 }
78
79 pub async fn flush(&mut self) -> Result<()> {
81 self.w.dyn_flush().await
82 }
83}
84
85impl embedded_io::ErrorType for Io<'_> {
86 type Error = Error;
87}
88
89impl embedded_io_async::Write for Io<'_> {
90 async fn write(&mut self, buf: &[u8]) -> core::result::Result<usize, Error> {
91 self.w.dyn_write_all(buf).await?;
92 Ok(buf.len())
93 }
94
95 async fn flush(&mut self) -> core::result::Result<(), Error> {
96 self.w.dyn_flush().await
97 }
98}