use crate::errors::Error;
use crate::hex::hex_byte_to_byte_value;
const MAC_BYTE_SIZE: usize = 6;
const MAC_READABLE_SIZE: usize = 17;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Mac {
raw: [u8; MAC_BYTE_SIZE],
}
impl Mac {
pub const fn new(raw: [u8; MAC_BYTE_SIZE]) -> Mac {
Mac { raw }
}
pub fn parse(input: &[u8]) -> Result<Mac, Error> {
if input.len() < MAC_READABLE_SIZE {
return Err(Error::InputTooShort);
}
if input.len() > MAC_READABLE_SIZE {
return Err(Error::InputTooLong);
}
let mut bytes = 0;
let mut raw = [0; MAC_BYTE_SIZE];
for byte in input.split(|&c| c == b':') {
if bytes >= MAC_BYTE_SIZE {
return Err(Error::TooManyOctets);
}
if byte.len() != 2 {
return Err(Error::IllegalCharacter);
}
raw[bytes] = hex_byte_to_byte_value(byte[0])? << 4 | hex_byte_to_byte_value(byte[1])?;
bytes += 1;
}
if bytes != MAC_BYTE_SIZE {
return Err(Error::InsufficientOctets);
}
Ok(Mac { raw })
}
}
#[cfg(test)]
mod tests {
use super::Mac;
use crate::errors::Error;
#[test]
fn parse_mac() {
assert_eq!(
Mac::parse("00:00:ec:00:5e:20".as_bytes()),
Ok(Mac::new([0, 0, 236, 0, 94, 32]))
);
assert_eq!(
Mac::parse("00:00:ec:00:5e".as_bytes()),
Err(Error::InputTooShort),
);
assert_eq!(
Mac::parse("00:00:ec:00:5e:20:32".as_bytes()),
Err(Error::InputTooLong),
);
assert_eq!(
Mac::parse("00:00:ece:00:5:20".as_bytes()),
Err(Error::IllegalCharacter),
);
assert_eq!(
Mac::parse("00:00:ec:0g:5e:20".as_bytes()),
Err(Error::IllegalCharacter),
);
}
}