use crate::error::ScriptError;
pub fn decode_hex(hex: &str) -> Result<Vec<u8>, ScriptError> {
if hex.len() % 2 != 0 {
return Err(ScriptError::InvalidHex);
}
let mut bytes = Vec::with_capacity(hex.len() / 2);
for i in (0..hex.len()).step_by(2) {
let pair = &hex[i..i + 2];
let byte = u8::from_str_radix(pair, 16).map_err(|_| ScriptError::InvalidHex)?;
bytes.push(byte);
}
Ok(bytes)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_string() {
assert_eq!(decode_hex("").unwrap(), vec![]);
}
#[test]
fn single_byte() {
assert_eq!(decode_hex("00").unwrap(), vec![0x00]);
assert_eq!(decode_hex("ff").unwrap(), vec![0xff]);
}
#[test]
fn mixed_case() {
assert_eq!(decode_hex("FF").unwrap(), vec![0xff]);
assert_eq!(decode_hex("aAbB").unwrap(), vec![0xaa, 0xbb]);
}
#[test]
fn multi_byte() {
assert_eq!(
decode_hex("deadbeef").unwrap(),
vec![0xde, 0xad, 0xbe, 0xef]
);
}
#[test]
fn odd_length() {
assert_eq!(decode_hex("0"), Err(ScriptError::InvalidHex));
assert_eq!(decode_hex("abc"), Err(ScriptError::InvalidHex));
}
#[test]
fn invalid_characters() {
assert_eq!(decode_hex("gg"), Err(ScriptError::InvalidHex));
assert_eq!(decode_hex("0x00"), Err(ScriptError::InvalidHex));
}
}