#![cfg_attr(not(feature = "std"), no_std)]
#![allow(async_fn_in_trait)]
use core::fmt::Debug;
use embedded_io::ErrorType;
#[derive(Debug, Default, Clone, PartialEq, PartialOrd)]
pub struct AwriteBuf<T, U> {
buf: T,
sink: U,
pos: usize,
}
impl<T, U> AwriteBuf<T, U> {
pub fn new(buf: T, sink: U) -> Self {
Self { buf, sink, pos: 0 }
}
pub fn into_sink(self) -> U {
self.sink
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum Error<E> {
Sync(embedded_io::SliceWriteError),
Async(E),
}
impl<E: embedded_io::Error> embedded_io::Error for Error<E> {
fn kind(&self) -> embedded_io::ErrorKind {
match self {
Self::Async(e) => e.kind(),
Self::Sync(e) => e.kind(),
}
}
}
impl<T, U: ErrorType> ErrorType for AwriteBuf<T, U> {
type Error = Error<U::Error>;
}
impl<T: AsMut<[u8]>, U: ErrorType> embedded_io::Write for AwriteBuf<T, U> {
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
let mut sli = &mut self.buf.as_mut()[self.pos..];
let written = sli.write(buf).map_err(Error::Sync)?;
self.pos += written;
Ok(written)
}
fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
impl<T: AsRef<[u8]> + AsMut<[u8]>, U: embedded_io_async::Write> embedded_io_async::Write
for AwriteBuf<T, U>
{
async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
embedded_io::Write::write(self, buf)
}
async fn flush(&mut self) -> Result<(), Self::Error> {
self.sink
.write_all(&self.buf.as_ref()[..self.pos])
.await
.map_err(Error::Async)?;
self.pos = 0;
Ok(())
}
}
#[macro_export]
macro_rules! awrite {
($aw:expr, $($tt:tt)*) => {
match write!($aw, $($tt)*) {
Ok(_) => embedded_io_async::Write::flush(&mut $aw).await.map_err(Into::into),
e => e
}
};
}
#[macro_export]
macro_rules! awriteln {
($aw:expr $(,)?) => {
awrite!($aw, "\n")
};
($aw:expr, $($tt:tt)*) => {
match writeln!($aw, $($tt)*) {
Ok(_) => embedded_io_async::Write::flush(&mut $aw).await.map_err(Into::into),
e => e
}
};
}