diff --git a/embedded-io-adapters/Cargo.toml b/embedded-io-adapters/Cargo.toml index ea88ee65..90dbdd9d 100644 --- a/embedded-io-adapters/Cargo.toml +++ b/embedded-io-adapters/Cargo.toml @@ -13,11 +13,13 @@ categories = [ ] [features] +default = ["digest"] std = ["embedded-io/std"] tokio-1 = ["std", "dep:tokio", "dep:embedded-io-async", "embedded-io-async?/std"] futures-03 = ["std", "dep:futures", "dep:embedded-io-async", "embedded-io-async?/std"] [dependencies] +digest = { version = "0.10.7", default-features = false, optional = true } embedded-io = { version = "0.6", path = "../embedded-io" } embedded-io-async = { version = "0.6.1", path = "../embedded-io-async", optional = true } diff --git a/embedded-io-adapters/src/digest.rs b/embedded-io-adapters/src/digest.rs new file mode 100644 index 00000000..ebc6c2aa --- /dev/null +++ b/embedded-io-adapters/src/digest.rs @@ -0,0 +1,108 @@ +//! Adapters to/from `digest::Digest` traits e.g. sha2::Sha256 + +use core::convert::Infallible; +use digest::Update; +use embedded_io::{ErrorType, Write}; + +/// Adapter from `digest::Digest` traits. +#[derive(Clone)] +pub struct FromDigest { + inner: T, +} + +impl FromDigest { + /// Create a new adapter. + pub fn new(inner: T) -> Self { + Self { inner } + } + + /// Consume the adapter, returning the inner object. + pub fn into_inner(self) -> T { + self.inner + } +} + +impl FromDigest { + /// Borrow the inner object. + pub fn inner(&self) -> &T { + &self.inner + } + + /// Mutably borrow the inner object. + pub fn inner_mut(&mut self) -> &mut T { + &mut self.inner + } +} + +impl ErrorType for FromDigest { + type Error = Infallible; +} + +impl Write for FromDigest { + fn write(&mut self, data: &[u8]) -> Result::Error> { + T::update(&mut self.inner, data); + Ok(data.len()) + } + fn flush(&mut self) -> Result<(), ::Error> { + Ok(()) + } +} + +impl Default for FromDigest { + fn default() -> Self { + Self { + inner: T::default(), + } + } +} + +/// Adapter to `digest::Digest` traits. +#[derive(Clone)] +pub struct ToDigest { + inner: T, +} + +impl ToDigest { + /// Create a new adapter. + pub fn new(inner: T) -> Self { + Self { inner } + } + + /// Consume the adapter, returning the inner object. + pub fn into_inner(self) -> T { + self.inner + } +} + +impl ToDigest { + /// Borrow the inner object. + pub fn inner(&self) -> &T { + &self.inner + } + + /// Mutably borrow the inner object. + pub fn inner_mut(&mut self) -> &mut T { + &mut self.inner + } +} + +impl Default for ToDigest { + fn default() -> Self { + Self { + inner: T::default(), + } + } +} + +impl + Write> Update for ToDigest { + fn update(&mut self, data: &[u8]) { + match self.inner.write_all(data) { + Ok(()) => {} + Err(_) => unreachable!(), + } + match self.inner.flush() { + Ok(()) => {} + Err(_) => unreachable!(), + } + } +} diff --git a/embedded-io-adapters/src/lib.rs b/embedded-io-adapters/src/lib.rs index c5e6710a..6ee37611 100644 --- a/embedded-io-adapters/src/lib.rs +++ b/embedded-io-adapters/src/lib.rs @@ -16,3 +16,7 @@ pub mod futures_03; #[cfg(feature = "tokio-1")] #[cfg_attr(docsrs, doc(cfg(feature = "tokio-1")))] pub mod tokio_1; + +#[cfg(feature = "digest")] +#[cfg_attr(docsrs, doc(cfg(feature = "digest")))] +pub mod digest;