use std::fmt::Write;
pub fn encode(bytes: impl AsRef<[u8]>) -> String {
let data = bytes.as_ref();
let mut s = String::with_capacity(data.len() * 2);
for b in data {
let _ = write!(s, "{b:02x}");
}
s
}
const DECODE_MAX_LEN: usize = 8 * 1024 * 1024;
#[must_use]
pub fn decode(s: &str) -> Option<Vec<u8>> {
if s.len() % 2 != 0 || s.len() > DECODE_MAX_LEN {
return None;
}
let bytes = s.as_bytes();
let mut out = Vec::with_capacity(s.len() / 2);
for i in (0..bytes.len()).step_by(2) {
let hi = nibble(bytes[i])?;
let lo = nibble(bytes[i + 1])?;
out.push((hi << 4) | lo);
}
Some(out)
}
fn nibble(b: u8) -> Option<u8> {
match b {
b'0'..=b'9' => Some(b - b'0'),
b'a'..=b'f' => Some(b - b'a' + 10),
b'A'..=b'F' => Some(b - b'A' + 10),
_ => None,
}
}