1use core::str::FromStr;
2use std::error;
3use std::fmt;
4
5#[cfg(feature = "serde")]
6use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
7
8#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default, Debug)]
10pub struct MacAddr(pub u8, pub u8, pub u8, pub u8, pub u8, pub u8);
11
12impl MacAddr {
13 pub fn new(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8) -> MacAddr {
15 MacAddr(a, b, c, d, e, f)
16 }
17 pub fn from_octets(octets: [u8; 6]) -> MacAddr {
19 MacAddr(
20 octets[0], octets[1], octets[2], octets[3], octets[4], octets[5],
21 )
22 }
23 pub fn octets(&self) -> [u8; 6] {
25 [self.0, self.1, self.2, self.3, self.4, self.5]
26 }
27 pub fn address(&self) -> String {
29 format!(
30 "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
31 self.0, self.1, self.2, self.3, self.4, self.5
32 )
33 }
34 pub fn zero() -> MacAddr {
36 MacAddr(0, 0, 0, 0, 0, 0)
37 }
38 pub fn broadcast() -> MacAddr {
40 MacAddr(0xff, 0xff, 0xff, 0xff, 0xff, 0xff)
41 }
42 pub fn from_hex_format(hex_mac_addr: &str) -> MacAddr {
44 if hex_mac_addr.len() != 17 {
45 return MacAddr(0, 0, 0, 0, 0, 0);
46 }
47 let fields: Vec<&str> = hex_mac_addr.split(":").collect();
48 let o1: u8 = u8::from_str_radix(&fields[0], 0x10).unwrap_or(0);
49 let o2: u8 = u8::from_str_radix(&fields[1], 0x10).unwrap_or(0);
50 let o3: u8 = u8::from_str_radix(&fields[2], 0x10).unwrap_or(0);
51 let o4: u8 = u8::from_str_radix(&fields[3], 0x10).unwrap_or(0);
52 let o5: u8 = u8::from_str_radix(&fields[4], 0x10).unwrap_or(0);
53 let o6: u8 = u8::from_str_radix(&fields[5], 0x10).unwrap_or(0);
54 MacAddr(o1, o2, o3, o4, o5, o6)
55 }
56}
57
58impl std::fmt::Display for MacAddr {
59 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
60 let _ = write!(
61 f,
62 "{:<02x}:{:<02x}:{:<02x}:{:<02x}:{:<02x}:{:<02x}",
63 self.0, self.1, self.2, self.3, self.4, self.5
64 );
65 Ok(())
66 }
67}
68
69#[cfg(feature = "serde")]
70impl Serialize for MacAddr {
71 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
73 if serializer.is_human_readable() {
74 serializer.collect_str(self)
75 } else {
76 serializer.serialize_bytes(&[self.0, self.1, self.2, self.3, self.4, self.5])
77 }
78 }
79}
80
81#[cfg(feature = "serde")]
82impl<'de> Deserialize<'de> for MacAddr {
83 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
85 struct MacAddrVisitor;
86 impl<'de> de::Visitor<'de> for MacAddrVisitor {
87 type Value = MacAddr;
88
89 fn visit_str<E: de::Error>(self, value: &str) -> Result<MacAddr, E> {
90 value.parse().map_err(|err| E::custom(err))
91 }
92
93 fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<MacAddr, E> {
94 if v.len() == 6 {
95 Ok(MacAddr::new(v[0], v[1], v[2], v[3], v[4], v[5]))
96 } else {
97 Err(E::invalid_length(v.len(), &self))
98 }
99 }
100
101 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
102 write!(
103 formatter,
104 "either a string representation of a MAC address or 6-element byte array"
105 )
106 }
107 }
108
109 if deserializer.is_human_readable() {
111 deserializer.deserialize_str(MacAddrVisitor)
112 } else {
113 deserializer.deserialize_bytes(MacAddrVisitor)
114 }
115 }
116}
117
118#[derive(Copy, Debug, PartialEq, Eq, Clone)]
120pub enum ParseMacAddrError {
121 TooManyComponents,
123 TooFewComponents,
125 InvalidComponent,
127}
128
129impl error::Error for ParseMacAddrError {}
130
131impl ParseMacAddrError {
132 fn description(&self) -> &str {
133 match *self {
134 ParseMacAddrError::TooManyComponents => "Too many components in a MAC address string",
135 ParseMacAddrError::TooFewComponents => "Too few components in a MAC address string",
136 ParseMacAddrError::InvalidComponent => "Invalid component in a MAC address string",
137 }
138 }
139}
140
141impl fmt::Display for ParseMacAddrError {
142 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
143 write!(f, "{}", self.description())
144 }
145}
146
147impl FromStr for MacAddr {
148 type Err = ParseMacAddrError;
149 fn from_str(s: &str) -> Result<MacAddr, ParseMacAddrError> {
150 let mut parts = [0u8; 6];
151 let splits = s.split(':');
152 let mut i = 0;
153 for split in splits {
154 if i == 6 {
155 return Err(ParseMacAddrError::TooManyComponents);
156 }
157 match u8::from_str_radix(split, 16) {
158 Ok(b) if split.len() != 0 => parts[i] = b,
159 _ => return Err(ParseMacAddrError::InvalidComponent),
160 }
161 i += 1;
162 }
163
164 if i == 6 {
165 Ok(MacAddr(
166 parts[0], parts[1], parts[2], parts[3], parts[4], parts[5],
167 ))
168 } else {
169 Err(ParseMacAddrError::TooFewComponents)
170 }
171 }
172}