1use std::fmt;
14use std::str::FromStr;
15
16use serde::de::{Deserialize, Deserializer, Error};
17use serde::ser::{Serialize, Serializer};
18
19pub const MAC_ADDR_LEN: u8 = 6;
21
22#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
24#[repr(transparent)]
25pub struct MacAddr {
27 bytes: [u8; MAC_ADDR_LEN as usize],
28}
29
30impl fmt::Display for MacAddr {
31 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 let b = &self.bytes;
33 write!(
34 f,
35 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
36 b[0], b[1], b[2], b[3], b[4], b[5]
37 )
38 }
39}
40
41impl From<[u8; 6]> for MacAddr {
42 fn from(bytes: [u8; 6]) -> Self {
43 Self { bytes }
44 }
45}
46
47impl From<MacAddr> for [u8; 6] {
48 fn from(mac: MacAddr) -> Self {
49 mac.bytes
50 }
51}
52
53impl FromStr for MacAddr {
54 type Err = String;
55 fn from_str(s: &str) -> Result<Self, Self::Err> {
61 let v: Vec<&str> = s.split(':').collect();
62 let mut bytes = [0u8; MAC_ADDR_LEN as usize];
63
64 if v.len() != MAC_ADDR_LEN as usize {
65 return Err(String::from(s));
66 }
67
68 for i in 0..MAC_ADDR_LEN as usize {
69 if v[i].len() != 2 {
70 return Err(String::from(s));
71 }
72 bytes[i] = u8::from_str_radix(v[i], 16).map_err(|_| String::from(s))?;
73 }
74
75 Ok(MacAddr { bytes })
76 }
77}
78
79impl MacAddr {
80 #[inline]
86 pub fn from_bytes_unchecked(src: &[u8]) -> MacAddr {
87 let mut bytes = [0u8; MAC_ADDR_LEN as usize];
90 bytes[..].copy_from_slice(src);
91
92 MacAddr { bytes }
93 }
94
95 #[inline]
97 pub fn get_bytes(&self) -> &[u8] {
98 &self.bytes
99 }
100}
101
102impl Serialize for MacAddr {
103 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
104 where
105 S: Serializer,
106 {
107 Serialize::serialize(&self.to_string(), serializer)
108 }
109}
110
111impl<'de> Deserialize<'de> for MacAddr {
112 fn deserialize<D>(deserializer: D) -> Result<MacAddr, D::Error>
113 where
114 D: Deserializer<'de>,
115 {
116 let s = <std::string::String as Deserialize>::deserialize(deserializer)?;
117 MacAddr::from_str(&s).map_err(|_| D::Error::custom("The provided MAC address is invalid."))
118 }
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124
125 #[test]
126 fn test_mac_addr() {
127 MacAddr::from_str("aa:aa:aa:aa:aa:aa:aa").unwrap_err();
129
130 MacAddr::from_str("aa:aa:aa:aa:aa:ax").unwrap_err();
132
133 MacAddr::from_str("aa:aa:aa:aa:aa:b").unwrap_err();
135
136 MacAddr::from_str("aa:aa:aa:aa:aa:bbb").unwrap_err();
138
139 let mac = MacAddr::from_str("12:34:56:78:9a:BC").unwrap();
140
141 println!("parsed MAC address: {}", mac);
142
143 let bytes = mac.get_bytes();
144 assert_eq!(bytes, [0x12u8, 0x34, 0x56, 0x78, 0x9a, 0xbc]);
145 }
146
147 #[test]
148 fn test_mac_addr_serialization_and_deserialization() {
149 let mac: MacAddr =
150 serde_json::from_str("\"12:34:56:78:9a:bc\"").expect("MacAddr deserialization failed.");
151
152 let bytes = mac.get_bytes();
153 assert_eq!(bytes, [0x12u8, 0x34, 0x56, 0x78, 0x9a, 0xbc]);
154
155 let s = serde_json::to_string(&mac).expect("MacAddr serialization failed.");
156 assert_eq!(s, "\"12:34:56:78:9a:bc\"");
157 }
158}