bitgrep 0.1.5

Binary grep for numerical data types
Documentation
use std::{fmt::Write, num::ParseIntError};

use thiserror::Error;

#[derive(Debug, Error, PartialEq)]
pub enum DecodeHexError {
    #[error("Could not parse hex number: {0}")]
    ParseIntError(#[from] std::num::ParseIntError),
    #[error("Invalid hex string format: {0}")]
    InvalidHexFormat(String),
}

pub fn decode(s: &str) -> Result<Vec<u8>, DecodeHexError> {
    if s.len() % 2 != 0 {
        return Err(DecodeHexError::InvalidHexFormat(s.to_string()));
    }

    let odd_chars = s.chars().step_by(2);
    let even_chars = s.chars().skip(1).step_by(2);

    let hex_pairs = odd_chars
        .zip(even_chars)
        .map(|(c1, c2)| String::from(c1) + &String::from(c2));

    let result: Result<Vec<u8>, ParseIntError> = hex_pairs
        .map(|pair| u8::from_str_radix(&pair, 16))
        .collect();

    return Ok(result?);
}

pub fn encode<T>(bytes: T) -> String
where
    T: AsRef<[u8]>,
{
    let mut result = String::new();
    for byte in bytes.as_ref() {
        write!(&mut result, "{byte:x}").expect("should write to string");
    }

    return result;
}