use std::string::String;
const HEXADECIMAL: &str = "0123456789abcdef";
pub struct Hex;
impl Hex {
pub fn encode<T: AsRef<[u8]>>(data: T) -> String {
let bytes = data.as_ref();
if bytes.is_empty() {
return String::new();
}
bytes.iter().map(|byte| format!("{:02x}", byte)).collect()
}
pub fn encode_str(data: &str) -> String {
Self::encode(data.as_bytes())
}
pub fn decode(data: &str) -> Result<Vec<u8>, &'static str> {
if data.is_empty() {
return Ok(Vec::new());
}
if data.len() % 2 != 0 {
return Err("Invalid hexadecimal string: odd length");
}
if !data
.chars()
.all(|c| HEXADECIMAL.contains(c.to_ascii_lowercase()))
{
return Err("Invalid hexadecimal string: invalid characters");
}
(0..data.len())
.step_by(2)
.map(|i| u8::from_str_radix(&data[i..i + 2], 16))
.collect::<Result<Vec<u8>, _>>()
.map_err(|_| "Failed to parse hexadecimal")
}
pub fn decode_str(data: &str) -> Result<String, &'static str> {
let bytes = Self::decode(data)?;
String::from_utf8(bytes).map_err(|_| "Invalid UTF-8 sequence")
}
}