speck-core 0.2.0

Secure runtime package manager for MMU-less microcontrollers
Documentation
//! Hex encoding utilities

/// Extension trait for hex operations
pub trait HexExt {
    /// Encode as hex string
    fn to_hex(&self) -> String;
    /// Decode from hex string
    fn from_hex(s: &str) -> Result<Self, HexError> where Self: Sized;
}

impl HexExt for [u8] {
    fn to_hex(&self) -> String {
        self.iter().map(|b| format!("{:02x}", b)).collect()
    }
}

impl HexExt for Vec<u8> {
    fn to_hex(&self) -> String {
        self.as_slice().to_hex()
    }
    
    fn from_hex(s: &str) -> Result<Self, HexError> {
        let cleaned: String = s.chars().filter(|c| c.is_ascii_hexdigit()).collect();
        if cleaned.len() % 2 != 0 {
            return Err(HexError::OddLength);
        }
        
        cleaned.as_bytes()
            .chunks(2)
            .map(|chunk| {
                u8::from_str_radix(std::str::from_utf8(chunk).unwrap(), 16)
                    .map_err(|_| HexError::InvalidCharacter)
            })
            .collect::<Result<Vec<_>, _>>()
    }
}

/// Hex decoding errors
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HexError {
    /// Odd number of hex digits
    OddLength,
    /// Invalid character in input
    InvalidCharacter,
}

impl core::fmt::Display for HexError {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            HexError::OddLength => write!(f, "odd number of hex digits"),
            HexError::InvalidCharacter => write!(f, "invalid hex character"),
        }
    }
}

impl core::error::Error for HexError {}