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