1use std::fmt;
9use std::result::Result;
10
11use serde::de::{Deserialize, Deserializer, Error};
12use serde::ser::{Serialize, Serializer};
13
14pub const MAC_ADDR_LEN: usize = 6;
16
17#[derive(Debug)]
18pub enum MacError {
19 MacLengthError(usize),
20}
21
22#[derive(Clone, Copy, Debug, Eq, PartialEq)]
24pub struct MacAddr {
25 bytes: [u8; MAC_ADDR_LEN],
26}
27
28impl MacAddr {
29 pub fn parse_str<S>(s: &S) -> Result<MacAddr, &str>
32 where
33 S: AsRef<str> + ?Sized,
34 {
35 let v: Vec<&str> = s.as_ref().split(':').collect();
36 let mut bytes = [0u8; MAC_ADDR_LEN];
37
38 if v.len() != MAC_ADDR_LEN {
39 return Err(s.as_ref());
40 }
41
42 for i in 0..MAC_ADDR_LEN {
43 if v[i].len() != 2 {
44 return Err(s.as_ref());
45 }
46 bytes[i] = u8::from_str_radix(v[i], 16).map_err(|_| s.as_ref())?;
47 }
48
49 Ok(MacAddr { bytes })
50 }
51
52 #[inline]
56 pub fn from_bytes_unchecked(src: &[u8]) -> MacAddr {
57 let mut bytes = [0u8; MAC_ADDR_LEN];
58 let _ = &bytes[..].copy_from_slice(src);
59
60 MacAddr { bytes }
61 }
62
63 #[inline]
65 pub fn from_bytes(src: &[u8]) -> Result<MacAddr, MacError> {
66 if src.len() != MAC_ADDR_LEN {
67 return Err(MacError::MacLengthError(src.len()));
68 }
69 Ok(MacAddr::from_bytes_unchecked(src))
70 }
71
72 #[inline]
74 pub fn get_bytes(&self) -> &[u8] {
75 &self.bytes
76 }
77}
78
79impl fmt::Display for MacAddr {
80 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81 let b = &self.bytes;
82 write!(
83 f,
84 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
85 b[0], b[1], b[2], b[3], b[4], b[5]
86 )
87 }
88}
89
90impl Serialize for MacAddr {
91 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
92 where
93 S: Serializer,
94 {
95 self.to_string().serialize(serializer)
96 }
97}
98
99impl<'de> Deserialize<'de> for MacAddr {
100 fn deserialize<D>(deserializer: D) -> Result<MacAddr, D::Error>
101 where
102 D: Deserializer<'de>,
103 {
104 let s = String::deserialize(deserializer)?;
105 MacAddr::parse_str(&s).map_err(|_| D::Error::custom("The provided MAC address is invalid."))
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[test]
114 fn test_mac_addr() {
115 assert!(MacAddr::parse_str("aa:aa:aa:aa:aa:aa:aa").is_err());
117
118 assert!(MacAddr::parse_str("aa:aa:aa:aa:aa:ax").is_err());
120
121 assert!(MacAddr::parse_str("aa:aa:aa:aa:aa:b").is_err());
123
124 assert!(MacAddr::parse_str("aa:aa:aa:aa:aa:bbb").is_err());
126
127 let mac = MacAddr::parse_str("12:34:56:78:9a:BC").unwrap();
128
129 println!("parsed MAC address: {}", mac);
130
131 let bytes = mac.get_bytes();
132 assert_eq!(bytes, [0x12u8, 0x34, 0x56, 0x78, 0x9a, 0xbc]);
133 }
134
135 #[test]
136 fn test_from_bytes() {
137 let src1 = [0x01, 0x02, 0x03, 0x04, 0x05];
138 let src2 = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06];
139 let src3 = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
140
141 assert!(MacAddr::from_bytes(&src1[..]).is_err());
142
143 let x = MacAddr::from_bytes(&src2[..]).unwrap();
144 assert_eq!(x.to_string(), String::from("01:02:03:04:05:06"));
145
146 assert!(MacAddr::from_bytes(&src3[..]).is_err());
147 }
148
149 #[cfg(feature = "with-serde")]
150 #[test]
151 fn test_mac_addr_serialization_and_deserialization() {
152 let mac: MacAddr =
153 serde_json::from_str("\"12:34:56:78:9a:bc\"").expect("MacAddr deserialization failed.");
154
155 let bytes = mac.get_bytes();
156 assert_eq!(bytes, [0x12u8, 0x34, 0x56, 0x78, 0x9a, 0xbc]);
157
158 let s = serde_json::to_string(&mac).expect("MacAddr serialization failed.");
159 assert_eq!(s, "\"12:34:56:78:9a:bc\"");
160 }
161}