display_buffered 0.1.4

A small library that provides convinience functions to write all the elements into a writer with buffering
Documentation
//! Provides convinience functions to write all the elements into a writer with buffering

use std::{
    fmt::Display,
    io::{self, BufWriter, Write},
};

/// Writes all the items into the writer with buffering sepparating them with the new line
///
/// # Arguments
///
/// * values - iterator of values to print
/// * buf - buffer to write into
///
/// # Errors
///
/// Errors if the writing or flushing the buffer errors
///
/// # Example
///
/// ```ignore
/// use display_buffered::display_buffered;
///
/// use std::io::stdout;
///
/// display_buffered([10, 20, 30], stdout()).unwrap()
/// ```
pub fn display_buffered<I, T, W>(values: I, writer: W) -> Result<(), io::Error>
where
    T: Display,
    I: IntoIterator<Item = T>,
    W: Write,
{
    let values = values.into_iter().map(|item| format!("{item}\n"));

    write_buffered(values, writer)
}

/// Writes all the bytes from values into the writer with buffering without any separators.
/// Worth noting that values may also consist of String and &str and any other objects that can
/// be turned into &[u8] using as_ref method
///
/// # Arguments
///
/// * values - iterator of strings to print
/// * buf - buffer to write into
///
/// # Errors
///
/// Errors if the writing or flushing the buffer errors
///
/// # Example
///
/// ```ignore
/// use display_buffered::write_buffered_strings;
///
/// use std::io::stdout;
///
/// write_buffered_strings(["10", "20", "30"], stdout()).unwrap() // Prints 102030
/// ```
pub fn write_buffered<T, I, W>(values: I, writer: W) -> Result<(), io::Error>
where
    T: AsRef<[u8]>,
    I: IntoIterator<Item = T>,
    W: Write,
{
    let mut writer = BufWriter::new(writer);

    for bytes in values {
        writer.write_all(bytes.as_ref())?
    }

    writer.flush()
}

#[cfg(test)]
mod tests {
    use super::*;

    /// A Write implementation for testing
    struct Writer(Vec<u8>);

    impl Writer {
        fn new() -> Self {
            Self(Vec::new())
        }

        fn into_inner(self) -> Vec<u8> {
            self.0
        }
    }

    impl Write for Writer {
        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
            self.0.extend(buf);
            Ok(buf.len())
        }

        fn flush(&mut self) -> io::Result<()> {
            Ok(())
        }
    }

    #[test]
    fn test_display_buffered() {
        let mut writer = Writer::new();
        display_buffered([10, 20], &mut writer).unwrap();
        assert_eq!(writer.into_inner(), b"10\n20\n")
    }

    #[test]
    fn test_write_buffered_with_slices() {
        let mut writer = Writer::new();
        write_buffered(["It ", "Works"], &mut writer).unwrap();
        assert_eq!(writer.into_inner(), b"It Works")
    }

    #[test]
    fn test_write_buffered_with_strings() {
        let mut writer = Writer::new();
        write_buffered(["It ".to_owned(), "Works".to_owned()], &mut writer).unwrap();
        assert_eq!(writer.into_inner(), b"It Works")
    }

    #[test]
    fn test_write_buffered_with_bytes() {
        let mut writer = Writer::new();
        let values: [&[u8]; 2] = [b"It ", b"Works"];
        write_buffered(values, &mut writer).unwrap();
        assert_eq!(writer.into_inner(), b"It Works")
    }
}