From ad4867c53d0cf7c5e683b321efed6de47d85f1f4 Mon Sep 17 00:00:00 2001 From: Stanislav Ravas Date: Mon, 6 May 2024 23:59:52 +0200 Subject: [PATCH] feat: implement embedded-io and embedded-io-async traits Allows much better interoperatibility with other embedded rust projects, which by now usually have support for embedded-io traits. --- Cargo.toml | 7 ++++- src/eio.rs | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ src/eio_async.rs | 13 ++++++++ src/lib.rs | 4 +++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 src/eio.rs create mode 100644 src/eio_async.rs diff --git a/Cargo.toml b/Cargo.toml index 1cc635dfb..e365a2512 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,9 @@ bitflags = "1" cty = "0.2.1" delog = "0.1.0" generic-array = "0.14" -heapless = "0.7" +heapless = "0.8" +embedded-io = { version = "0.6.1", optional = true } +embedded-io-async = { version = "0.6.1", optional = true } [dependencies.cstr_core] default-features = false @@ -44,6 +46,9 @@ ll-assertions = ["littlefs2-sys/assertions"] # enable trace in backend C code ll-trace = ["littlefs2-sys/trace"] c-stubs = [] +eio = ["dep:embedded-io"] +eio-async = ["eio", "dep:embedded-io-async"] + log-all = [] log-none = [] diff --git a/src/eio.rs b/src/eio.rs new file mode 100644 index 000000000..ab9a2c122 --- /dev/null +++ b/src/eio.rs @@ -0,0 +1,77 @@ +use crate::io; + +impl embedded_io::Error for io::Error { + fn kind(&self) -> embedded_io::ErrorKind { + match self { + io::Error::Success + | io::Error::Io + | io::Error::Corruption + | io::Error::PathNotDir + | io::Error::PathIsDir + | io::Error::DirNotEmpty + | io::Error::FileTooBig + | io::Error::NoSpace + | io::Error::NoAttribute + | io::Error::Unknown(_) => embedded_io::ErrorKind::Other, + io::Error::EntryAlreadyExisted => embedded_io::ErrorKind::AlreadyExists, + io::Error::NoSuchEntry => embedded_io::ErrorKind::NotFound, + io::Error::BadFileDescriptor | io::Error::Invalid | io::Error::FilenameTooLong => { + embedded_io::ErrorKind::InvalidInput + } + io::Error::NoMemory => embedded_io::ErrorKind::OutOfMemory, + } + } +} + +pub struct Reader<'a, T: io::Read>(pub(crate) &'a T); + +impl<'a, T: io::Read> Reader<'a, T> { + pub fn new(read: &'a T) -> Self { + Self(read) + } +} + +impl<'a, T: io::Read> embedded_io::ErrorType for Reader<'a, T> { + type Error = io::Error; +} + +impl<'a, T: io::Read> embedded_io::Read for Reader<'a, T> { + fn read(&mut self, buf: &mut [u8]) -> Result { + self.0.read(buf) + } + + fn read_exact( + &mut self, + buf: &mut [u8], + ) -> Result<(), embedded_io::ReadExactError> { + self.0 + .read_exact(buf) + .map_err(|e| embedded_io::ReadExactError::Other(e)) + } +} + +pub struct Writer<'a, T: io::Write>(pub(crate) &'a T); + +impl<'a, T: io::Write> Writer<'a, T> { + pub fn new(write: &'a T) -> Self { + Self(write) + } +} + +impl<'a, T: io::Write> embedded_io::ErrorType for Writer<'a, T> { + type Error = io::Error; +} + +impl<'a, T: io::Write> embedded_io::Write for Writer<'a, T> { + fn write(&mut self, buf: &[u8]) -> Result { + self.0.write(buf) + } + + fn flush(&mut self) -> Result<(), Self::Error> { + self.0.flush() + } + + fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> { + self.0.write_all(buf) + } +} diff --git a/src/eio_async.rs b/src/eio_async.rs new file mode 100644 index 000000000..db672b47e --- /dev/null +++ b/src/eio_async.rs @@ -0,0 +1,13 @@ +use crate::io; + +impl<'a, T: io::Read> embedded_io_async::Read for super::eio::Reader<'a, T> { + async fn read(&mut self, buf: &mut [u8]) -> Result { + self.0.read(buf) + } +} + +impl<'a, T: io::Write> embedded_io_async::Write for super::eio::Writer<'a, T> { + async fn write(&mut self, buf: &[u8]) -> Result { + self.0.write(buf) + } +} diff --git a/src/lib.rs b/src/lib.rs index a7a78e2b5..12a33bc39 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -141,6 +141,10 @@ mod c_stubs; pub mod consts; pub mod driver; +#[cfg(feature = "eio")] +pub mod eio; +#[cfg(feature = "eio-async")] +pub mod eio_async; pub mod fs; pub mod io; pub mod object_safe;