use crate::Result;
use crate::error::DdError;
pub fn hex_encode(bytes: &[u8]) -> String {
const HEX: &[u8] = b"0123456789abcdef";
let mut out = String::with_capacity(bytes.len() * 2);
for b in bytes {
out.push(HEX[(b >> 4) as usize] as char);
out.push(HEX[(b & 0x0f) as usize] as char);
}
out
}
pub fn hex_decode(s: &str) -> Result<Vec<u8>> {
if !s.len().is_multiple_of(2) {
return Err(DdError::protocol(
crate::error::ErrorCode::Ddp1005BadIdentifier,
"odd hex length",
));
}
let mut out = Vec::with_capacity(s.len() / 2);
let bytes = s.as_bytes();
for i in (0..bytes.len()).step_by(2) {
let hi = hex_val(bytes[i])?;
let lo = hex_val(bytes[i + 1])?;
out.push((hi << 4) | lo);
}
Ok(out)
}
fn hex_val(c: u8) -> Result<u8> {
match c {
b'0'..=b'9' => Ok(c - b'0'),
b'a'..=b'f' => Ok(c - b'a' + 10),
b'A'..=b'F' => Ok(c - b'A' + 10),
_ => Err(DdError::protocol(
crate::error::ErrorCode::Ddp1005BadIdentifier,
"invalid hex",
)),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hex_roundtrip() {
let b = [0x7f, 0x4a, 0x91];
assert_eq!(hex_decode(&hex_encode(&b)).unwrap(), b);
}
}