1const MAC_ADDRESS_SIZE: usize = 6;
2
3addr_ty!(
4 #[doc(alias = "Eui48Addr")]
6 #[derive(Eq, PartialEq, Ord, PartialOrd, Hash)]
7 MacAddr[MAC_ADDRESS_SIZE]
8);
9
10#[cfg(test)]
11mod tests {
12 use super::*;
13 use crate::{ParseError, TestCase};
14
15 use std::{string::ToString, vec, vec::Vec};
16
17 fn test_cases() -> Vec<TestCase<MAC_ADDRESS_SIZE>> {
18 vec![
19 TestCase {
21 input: "00:00:5e:00:53:01",
22 output: Some(vec![0x00, 0x00, 0x5e, 0x00, 0x53, 0x01]),
23 err: None,
24 },
25 TestCase {
26 input: "00-00-5e-00-53-01",
27 output: Some(vec![0x00, 0x00, 0x5e, 0x00, 0x53, 0x01]),
28 err: None,
29 },
30 TestCase {
31 input: "0000.5e00.5301",
32 output: Some(vec![0x00, 0x00, 0x5e, 0x00, 0x53, 0x01]),
33 err: None,
34 },
35 TestCase {
36 input: "ab:cd:ef:AB:CD:EF",
37 output: Some(vec![0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef]),
38 err: None,
39 },
40 TestCase {
42 input: "01.02.03.04.05.06",
43 output: None,
44 err: Some(ParseError::InvalidSeparator(b'.')),
45 },
46 TestCase {
47 input: "01:02:03:04:05:06:",
48 output: None,
49 err: Some(ParseError::InvalidLength(18)),
50 },
51 TestCase {
52 input: "x1:02:03:04:05:06",
53 output: None,
54 err: Some(ParseError::InvalidHexDigit([b'x', b'1'])),
55 },
56 TestCase {
57 input: "01-02:03:04:05:06",
58 output: None,
59 err: Some(ParseError::UnexpectedSeparator {
60 expected: b'-',
61 actual: b':',
62 }),
63 },
64 ]
65 }
66
67 #[test]
68 fn parse() {
69 let cases = test_cases();
70 for (i, test) in cases.iter().enumerate() {
71 let result = MacAddr::try_from(test.input);
72
73 match (result, &test.output) {
74 (Ok(out), Some(expected)) => {
75 assert_eq!(
76 out.as_bytes(),
77 expected.as_slice(),
78 "Test case {}: MacAddr::parse({}) output mismatch",
79 i,
80 test.input
81 );
82
83 if test.err.is_none() {
85 let formatted = out.to_string();
86 let round_trip = MacAddr::try_from(formatted.as_str());
87 assert!(
88 round_trip.is_ok(),
89 "Test case {}: Round-trip parse failed for {}",
90 i,
91 formatted
92 );
93 assert_eq!(
94 round_trip.unwrap(),
95 out,
96 "Test case {}: Round-trip value mismatch",
97 i
98 );
99 }
100 }
101 (Err(err), None) => {
102 assert_eq!(
103 Some(&err),
104 test.err.as_ref(),
105 "Test case {}: Expected error containing '{:?}', got '{:?}'",
106 i,
107 test.err,
108 err
109 );
110 }
111 (Ok(out), None) => {
112 panic!(
113 "Test case {}: Expected error '{:?}', got success: {:?}",
114 i, test.err, out
115 );
116 }
117 (Err(err), Some(expected)) => {
118 panic!(
119 "Test case {}: Expected {:?}, got error: {:?}",
120 i, expected, err
121 );
122 }
123 }
124 }
125 }
126
127 #[test]
128 fn formatted() {
129 let addr = MacAddr::try_from("00:00:5e:00:53:01").unwrap();
130 assert_eq!(addr.to_string(), "00:00:5e:00:53:01");
131
132 let dot = addr.to_dot_seperated_array();
133 let dot_str = core::str::from_utf8(&dot).unwrap();
134 assert_eq!(dot_str, "0000.5e00.5301");
135
136 let dashed = addr.to_hyphen_seperated_array();
137 let dashed_str = core::str::from_utf8(&dashed).unwrap();
138 assert_eq!(dashed_str, "00-00-5e-00-53-01");
139 }
140
141 #[cfg(feature = "serde")]
142 #[test]
143 fn serde_human_readable() {
144 let addr = MacAddr::try_from("00:00:5e:00:53:01").unwrap();
145 let json = serde_json::to_string(&addr).unwrap();
146 assert_eq!(json, "\"00:00:5e:00:53:01\"");
147
148 let addr2: MacAddr = serde_json::from_str(&json).unwrap();
149 assert_eq!(addr, addr2);
150 }
151
152 #[cfg(feature = "serde")]
153 #[test]
154 fn serde_human_unreadable() {
155 let addr = MacAddr::try_from("00:00:5e:00:53:01").unwrap();
156 let json = bincode::serialize(&addr).unwrap();
157 assert_eq!(json, [0, 0, 94, 0, 83, 1]);
158 assert_eq!(addr.octets(), [0, 0, 94, 0, 83, 1]);
159
160 let addr2: MacAddr = bincode::deserialize(&json).unwrap();
161 assert_eq!(addr, addr2);
162
163 let addr3 = MacAddr::new([0, 0, 94, 0, 83, 1]);
164 assert_eq!(addr, addr3);
165
166 println!("{:?}", addr);
167 }
168}