hxd 0.1.0

A simple and configurable hexdump library
Documentation
use std::{
    convert::Infallible,
    fmt::Debug,
    fs::File,
    io::{Stderr, Stdout, Write},
};

pub trait WriteHexdump: Sized {
    type Error: Debug;
    type Output;
    fn write_line(&mut self, s: &str) -> Result<(), Self::Error>;
    fn flush(&mut self) -> Result<(), Self::Error> {
        Ok(())
    }
    fn consume(r: Result<Self, Self::Error>) -> Self::Output;
}

#[doc(hidden)]
pub struct IOWriter<W: std::io::Write>(pub W);

impl<W: std::io::Write> WriteHexdump for IOWriter<W> {
    type Error = std::io::Error;
    type Output = Result<(), std::io::Error>;
    fn write_line(&mut self, s: &str) -> Result<(), Self::Error> {
        self.0.write_all(s.as_bytes())
    }
    fn flush(&mut self) -> Result<(), Self::Error> {
        self.0.flush()
    }
    fn consume(r: Result<Self, Self::Error>) -> Self::Output {
        r.map(|_| ())
    }
}

impl WriteHexdump for Stdout {
    type Error = std::io::Error;
    type Output = ();
    fn write_line(&mut self, s: &str) -> Result<(), std::io::Error> {
        self.write_all(s.as_bytes())
    }
    fn flush(&mut self) -> Result<(), Self::Error> {
        std::io::Write::flush(self)
    }
    fn consume(r: Result<Self, Self::Error>) -> Self::Output {
        r.unwrap();
        ()
    }
}

impl WriteHexdump for Stderr {
    type Error = std::io::Error;
    type Output = ();
    fn write_line(&mut self, s: &str) -> Result<(), std::io::Error> {
        self.write_all(s.as_bytes())
    }
    fn flush(&mut self) -> Result<(), Self::Error> {
        std::io::Write::flush(self)
    }
    fn consume(r: Result<Self, Self::Error>) -> Self::Output {
        r.unwrap();
        ()
    }
}

impl WriteHexdump for File {
    type Error = std::io::Error;
    type Output = Result<(), std::io::Error>;
    fn write_line(&mut self, s: &str) -> Result<(), std::io::Error> {
        self.write_all(s.as_bytes())
    }
    fn flush(&mut self) -> Result<(), Self::Error> {
        std::io::Write::flush(self)
    }
    fn consume(r: Result<Self, Self::Error>) -> Self::Output {
        r.map(|_| ())
    }
}

impl WriteHexdump for String {
    type Error = Infallible;
    type Output = String;
    fn write_line(&mut self, s: &str) -> Result<(), Self::Error> {
        self.push_str(s);
        Ok(())
    }
    fn consume(r: Result<Self, Self::Error>) -> Self::Output {
        r.unwrap()
    }
}

impl WriteHexdump for Vec<String> {
    type Error = Infallible;
    type Output = Vec<String>;
    fn write_line(&mut self, s: &str) -> Result<(), Self::Error> {
        self.push(s.to_string());
        Ok(())
    }
    fn consume(r: Result<Self, Self::Error>) -> Self::Output {
        r.unwrap()
    }
}

impl WriteHexdump for Vec<u8> {
    type Error = Infallible;
    type Output = Vec<u8>;
    fn write_line(&mut self, s: &str) -> Result<(), Self::Error> {
        self.extend_from_slice(s.as_bytes());
        Ok(())
    }
    fn consume(r: Result<Self, Self::Error>) -> Self::Output {
        r.unwrap()
    }
}

impl WriteHexdump for Vec<Vec<u8>> {
    type Error = Infallible;
    type Output = Vec<Vec<u8>>;
    fn write_line(&mut self, s: &str) -> Result<(), Self::Error> {
        self.push(s.as_bytes().to_vec());
        Ok(())
    }
    fn consume(r: Result<Self, Self::Error>) -> Self::Output {
        r.unwrap()
    }
}