hex_dump 0.1.5

A CLI that can read print and modify binary file
Documentation
#[allow(warnings)]
pub mod hex_vec {
    use std::error::Error;
    use std::fs::File;
    use std::io::{self, Read};
    use std::path::Path;
    const BYTES_PER_LINE: usize = 16;
    pub fn vec_to_hex(vec: &Vec<u8>) -> String {
        let hex_chars: Vec<char> = "0123456789abcdef".chars().collect();
        let mut hex_string = String::new();
        for byte in vec {
            hex_string.push(hex_chars[(byte >> 4) as usize]);
            hex_string.push(hex_chars[(byte & 0x0f) as usize]);
            hex_string.push(' ');
        }
        hex_string.to_ascii_uppercase()
    }
    pub fn hex_to_vec(hex_string: String) -> Vec<u8> {
        let mut vec = Vec::new();
        let mut chars = hex_string.chars().peekable();
        while let Some(c) = chars.next() {
            if let Some(nibble1) = "0123456789abcdef".find(c.to_ascii_lowercase()) {
                if let Some(nibble2) = chars
                    .next()
                    .and_then(|c| "0123456789abcdef".find(c.to_ascii_lowercase()))
                {
                    vec.push((nibble1 << 4 | nibble2) as u8);
                }
            }
        }
        vec
    }
    #[derive(Clone)]
    pub struct HexInfo {
        pub hex_vec: Vec<u8>,
        pub address_vec: Vec<String>,
    }
    pub fn read_file<P: AsRef<Path>>(path: P) -> io::Result<HexInfo> {
        let mut file = File::open(path)?;
        let mut buf = Vec::new();
        file.read_to_end(&mut buf)?;
        Ok(HexInfo {
            hex_vec: buf.clone(),
            address_vec: buf_to_address(buf.clone()),
        })
    }
    pub fn buf_to_address(buf: Vec<u8>) -> Vec<String> {
        let mut res = vec![];
        for (i, chunk) in buf.chunks(BYTES_PER_LINE).enumerate() {
            res.push(format!("{:08X}", i * BYTES_PER_LINE));
        }
        res
    }

    pub fn buf_to_hex(buf: Vec<u8>) -> Vec<String> {
        buf.into_iter()
            .map(|b| format!("{:02X}", b))
            .collect::<Vec<String>>()
    }

    pub fn hex_to_buf(hex_strings: Vec<String>) -> Vec<u8> {
        hex_strings
            .into_iter()
            .map(|hex_str| u8::from_str_radix(&hex_str, 16).unwrap())
            .collect::<Vec<u8>>()
    }

    pub fn find_position(
        address_vec: Vec<String>,
        addr: String,
        column: usize,
    ) -> Result<usize, usize> {
        let find_address_position = |addr_vec: Vec<String>, addr: String| -> Result<usize, usize> {
            addr_vec.binary_search_by(|address| address.cmp(&addr))
        };
        match find_address_position(address_vec, addr) {
            Ok(rows_num) => {
                let position = BYTES_PER_LINE * rows_num + column;
                Ok(position)
            }
            Err(e) => Err(0),
        }
    }
    pub fn desplay_hex(buf: Vec<u8>) -> io::Result<()> {
        println(format!(
            "{:^08}  0   1  2  3  4  5  6  7  8  9 10 11 12 13 14 15",
            "Adress"
        ));

        // 遍历缓冲区中每个字节,并打印十六进制和 ASCII 码表示
        for (i, chunk) in buf.chunks(BYTES_PER_LINE).enumerate() {
            // 打印十六进制表示
            print(format!("{:08X}  ", i * BYTES_PER_LINE));
            for b in chunk {
                print(format!("{:02X} ", b));
            }
            // 打印 ASCII 码表示
            for _ in chunk.len()..BYTES_PER_LINE {
                print(format!("   "));
            }
            print(format!(" |"));
            for b in chunk {
                if *b > 31 && *b < 127 {
                    print(format!("{}", *b as char));
                } else {
                    print(format!("."));
                }
            }
            println(format!("|"));
        }
        Ok(())
    }

    pub fn print(s: String) {
        use std::io::{self, Write};
        let mut stdout = io::stdout();
        match stdout.lock().write_all(s.as_bytes()) {
            Ok(_) => {}
            Err(_) => {
                std::process::exit(1);
            }
        }
        match stdout.flush() {
            Ok(_) => {}
            Err(_) => {
                std::process::exit(1);
            }
        }
    }
    pub fn println(s: String) {
        use std::io::{self, Write};
        let mut stdout = io::stdout();
        let mut s = s;
        s.push_str("\n");

        match stdout.lock().write_all(s.as_bytes()) {
            Ok(_) => {}
            Err(_) => {
                std::process::exit(1);
            }
        }
        match stdout.flush() {
            Ok(_) => {}
            Err(_) => {
                std::process::exit(1);
            }
        }
    }
}