ndn_transport/
mac_addr.rs

1//! Link-layer (MAC) address type shared by the transport, discovery, and face layers.
2
3/// A 6-byte IEEE 802 MAC address.
4#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
5pub struct MacAddr(pub [u8; 6]);
6
7impl MacAddr {
8    pub const BROADCAST: MacAddr = MacAddr([0xff; 6]);
9
10    pub const fn new(bytes: [u8; 6]) -> Self {
11        Self(bytes)
12    }
13
14    pub fn as_bytes(&self) -> &[u8; 6] {
15        &self.0
16    }
17}
18
19impl std::fmt::Display for MacAddr {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        let b = &self.0;
22        write!(
23            f,
24            "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
25            b[0], b[1], b[2], b[3], b[4], b[5]
26        )
27    }
28}
29
30impl std::str::FromStr for MacAddr {
31    type Err = &'static str;
32
33    fn from_str(s: &str) -> Result<Self, Self::Err> {
34        let parts: Vec<&str> = s.split(':').collect();
35        if parts.len() != 6 {
36            return Err("expected 6 colon-separated hex octets");
37        }
38        let mut bytes = [0u8; 6];
39        for (i, part) in parts.iter().enumerate() {
40            bytes[i] = u8::from_str_radix(part, 16).map_err(|_| "invalid hex octet")?;
41        }
42        Ok(MacAddr(bytes))
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49
50    #[test]
51    fn display_round_trips() {
52        let mac = MacAddr::new([0xde, 0xad, 0xbe, 0xef, 0x00, 0x01]);
53        let s = mac.to_string();
54        assert_eq!(s, "de:ad:be:ef:00:01");
55        let parsed: MacAddr = s.parse().unwrap();
56        assert_eq!(mac, parsed);
57    }
58
59    #[test]
60    fn broadcast() {
61        assert_eq!(MacAddr::BROADCAST.as_bytes(), &[0xff; 6]);
62        assert!(MacAddr::BROADCAST.as_bytes()[0] & 0x01 == 0x01);
63    }
64}