use crate::Exception;
pub struct HexUtil;
impl HexUtil {
pub fn to_hex(bytes: &[u8]) -> String {
let mut hex_str = String::new();
for byte in bytes {
hex_str += &format!("{:02x}", byte);
}
hex_str
}
pub fn to_bytes(hex: &str) -> Result<Vec<u8>, Exception> {
if hex.len() % 2 != 0 {
return Err(Exception::ParseError("Invalid hex string length".to_string()));
}
let mut bytes = Vec::with_capacity(hex.len() / 2);
let mut chars = hex.chars();
while let (Some(a), Some(b)) = (chars.next(), chars.next()) {
let byte = match u8::from_str_radix(&format!("{}{}", a, b), 16) {
Ok(byte) => byte,
Err(_) => return Err(Exception::ParseError("Invalid hex digit".to_string())),
};
bytes.push(byte);
}
Ok(bytes)
}
pub fn encode_hex_str(text: &str) -> String {
let bytes = text.as_bytes();
let hex_str = HexUtil::to_hex(bytes);
hex_str
}
pub fn decode_hex_str(hex: &str) -> Result<String, &'static str> {
if hex.len() % 2 != 0 {
return Err("Invalid hex string length");
}
let mut bytes = Vec::with_capacity(hex.len() / 2);
let mut chars = hex.chars();
while let (Some(a), Some(b)) = (chars.next(), chars.next()) {
let byte = match u8::from_str_radix(&format!("{}{}", a, b), 16) {
Ok(byte) => byte,
Err(_) => return Err("Invalid hex digit"),
};
bytes.push(byte);
}
match str::from_utf8(&bytes) {
Ok(s) => Ok(s.to_string()),
Err(_) => Err("Invalid UTF - 8 sequence"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_to_hex() {
let hex_str = HexUtil::to_hex(&[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
println!("{}", hex_str);
let bytes: Vec<u8> = "hello, rust!".bytes().collect();
let hex_str = HexUtil::to_hex(&bytes);
println!("{}", hex_str);
let bytes = "hello, rust!".to_string().as_bytes().to_vec();
let hex_str = HexUtil::to_hex(&bytes);
println!("{}", hex_str);
let str = String::from("hello, rust!");
let bytes = str.as_bytes();
let hex_str = HexUtil::to_hex(bytes);
println!("{}", hex_str);
}
#[test]
fn test_encode_decode_hex_str() {
let origin = "hello, rust!";
let hex_str = HexUtil::encode_hex_str(origin);
println!("{}", hex_str);
let decoded = HexUtil::decode_hex_str(&hex_str).unwrap();
println!("{}", decoded);
assert_eq!(origin, decoded);
}
}