extra-embedded-io-adapters 0.1.0

Implementations of embedded-io's Write trait for other crates' types
Documentation
//! Tools used in tests, providing a versatile implementation of [`embedded_io::Write`]

extern crate alloc;
use alloc::vec::Vec;

/// An alloc-logging writer that only accepts writes in chunks of `single_limit` (avoiding
/// false-positives that stem from mishandling partial writes) and only `total_limit` bytes in
/// total (to test error behavior).
pub struct DummyWriter {
    pub total_limit: usize,
    pub single_limit: usize,
    pub written: Vec<WriteEvent>,
}
#[derive(Debug)]
pub enum WriteEvent {
    Write(Vec<u8>),
    Flush,
}
#[derive(Debug, thiserror::Error)]
#[error("write exceeds the concfigured limit of the DummyWriter")]
pub struct DummyWriterFull;

impl DummyWriter {
    pub fn new() -> Self {
        Self {
            total_limit: 100,
            single_limit: 10,
            written: Vec::new(),
        }
    }

    pub fn all_written(&self) -> Vec<u8> {
        self.written
            .iter()
            .filter_map(|e| match e {
                WriteEvent::Write(d) => Some(d.iter()),
                WriteEvent::Flush => None,
            })
            .flatten()
            .copied()
            .collect()
    }
}

impl embedded_io::Error for DummyWriterFull {
    fn kind(&self) -> embedded_io::ErrorKind {
        panic!("We never inspect this")
    }
}

impl embedded_io::ErrorType for DummyWriter {
    type Error = DummyWriterFull;
}

impl embedded_io::Write for DummyWriter {
    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
        let buf = if buf.len() > self.single_limit {
            &buf[..self.single_limit]
        } else {
            buf
        };
        self.total_limit = self
            .total_limit
            .checked_sub(buf.len())
            .ok_or(DummyWriterFull)?;
        self.written.push(WriteEvent::Write(Vec::from(buf)));
        Ok(buf.len())
    }

    fn flush(&mut self) -> Result<(), Self::Error> {
        self.written.push(WriteEvent::Flush);
        Ok(())
    }
}