diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3421fa2a21..9df677aab0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -176,6 +176,7 @@ jobs: cargo check --target="${target}" --features="portable-atomic-critical-section" cargo check --target="${target}" --features="serde" cargo check --target="${target}" --features="ufmt" + cargo check --target="${target}" --features="embedded-io" env: target: ${{ matrix.target }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ba060d326..2962117a2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added + +- Added optional `embedded_io::Write` impl for `Vec`. + ### Changed - `bytes::BufMut` is now implemented on `VecInner`. diff --git a/Cargo.toml b/Cargo.toml index b259387798..0ac8db93cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,9 @@ ufmt = ["dep:ufmt", "dep:ufmt-write"] # Implement `defmt::Format`. defmt = ["dep:defmt"] +# Implement `embedded_io::Write` +embedded-io = ["dep:embedded-io"] + # Enable larger MPMC sizes. mpmc_large = [] @@ -54,6 +57,7 @@ serde = { version = "1", optional = true, default-features = false } ufmt = { version = "0.2", optional = true } ufmt-write = { version = "0.1", optional = true } defmt = { version = "1.0.1", optional = true } +embedded-io = { version = "0.6", optional = true } # for the pool module [target.'cfg(any(target_arch = "arm", target_pointer_width = "32", target_pointer_width = "64"))'.dependencies] diff --git a/src/embedded_io.rs b/src/embedded_io.rs new file mode 100644 index 0000000000..418529215b --- /dev/null +++ b/src/embedded_io.rs @@ -0,0 +1,55 @@ +use embedded_io::{Error, ErrorKind, ErrorType, Write}; + +use crate::{ + len_type::LenType, + vec::{VecInner, VecStorage}, + CapacityError, +}; + +impl Error for CapacityError { + fn kind(&self) -> ErrorKind { + ErrorKind::OutOfMemory + } +} + +impl + ?Sized> ErrorType for VecInner { + type Error = CapacityError; +} + +impl + ?Sized> Write for VecInner { + #[inline] + fn write(&mut self, buf: &[u8]) -> Result { + self.extend_from_slice(buf)?; + Ok(buf.len()) + } + + #[inline] + fn flush(&mut self) -> Result<(), Self::Error> { + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use crate::Vec; + use embedded_io::{Error, ErrorKind, Write}; + + fn write(w: &mut impl Write, data: &[u8]) -> Result<(), ErrorKind> { + w.write_all(data).map_err(|e| e.kind()) + } + + #[test] + fn test_write() { + let mut v: Vec = Vec::new(); + assert_eq!(v.len(), 0); + write(&mut v, &[1, 2]).unwrap(); + assert_eq!(v.len(), 2); + assert_eq!(v.as_slice(), &[1, 2]); + write(&mut v, &[3]).unwrap(); + assert_eq!(v.len(), 3); + assert_eq!(v.as_slice(), &[1, 2, 3]); + assert!(write(&mut v, &[4, 5]).is_err()); + assert_eq!(v.len(), 3); + assert_eq!(v.as_slice(), &[1, 2, 3]); + } +} diff --git a/src/lib.rs b/src/lib.rs index f9880690cf..f197e8f179 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -237,6 +237,9 @@ pub mod spsc; #[cfg(feature = "ufmt")] mod ufmt; +#[cfg(feature = "embedded-io")] +mod embedded_io; + /// Implementation details for macros. /// Do not use. Used for macros only. Not covered by semver guarantees. #[doc(hidden)]