hardware_address/
infini_band.rs

1addr_ty!(
2  /// Represents a physical 20-octet InfiniBand format address.
3  InfiniBandAddr[20]
4);
5
6#[cfg(test)]
7mod tests {
8  use super::*;
9  use crate::TestCase;
10
11  use std::{string::ToString, vec, vec::Vec};
12
13  const INFINI_BAND_ADDRESS_SIZE: usize = 20;
14
15  fn test_cases() -> Vec<TestCase<INFINI_BAND_ADDRESS_SIZE>> {
16    vec![
17      // RFC 4391, Section 9.1.1
18      TestCase {
19        input: "00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01",
20        output: Some(vec![
21          0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x5e,
22          0x10, 0x00, 0x00, 0x00, 0x01,
23        ]),
24        err: None,
25      },
26      TestCase {
27        input: "00-00-00-00-fe-80-00-00-00-00-00-00-02-00-5e-10-00-00-00-01",
28        output: Some(vec![
29          0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x5e,
30          0x10, 0x00, 0x00, 0x00, 0x01,
31        ]),
32        err: None,
33      },
34      TestCase {
35        input: "0000.0000.fe80.0000.0000.0000.0200.5e10.0000.0001",
36        output: Some(vec![
37          0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x5e,
38          0x10, 0x00, 0x00, 0x00, 0x01,
39        ]),
40        err: None,
41      },
42    ]
43  }
44
45  #[test]
46  fn parse() {
47    let cases = test_cases();
48    for (i, test) in cases.iter().enumerate() {
49      let result = InfiniBandAddr::try_from(test.input);
50
51      match (result, &test.output) {
52        (Ok(out), Some(expected)) => {
53          assert_eq!(
54            out.as_ref(),
55            expected.as_slice(),
56            "Test case {}: InfiniBandAddr::parse({}) output mismatch",
57            i,
58            test.input
59          );
60
61          // Test round-trip if this was a valid case
62          if test.err.is_none() {
63            let formatted = out.to_string();
64            let round_trip = InfiniBandAddr::try_from(formatted.as_str());
65            assert!(
66              round_trip.is_ok(),
67              "Test case {}: Round-trip parse failed for {}",
68              i,
69              formatted
70            );
71            assert_eq!(
72              round_trip.unwrap(),
73              out,
74              "Test case {}: Round-trip value mismatch",
75              i
76            );
77          }
78        }
79        (Err(err), None) => {
80          assert_eq!(
81            Some(&err),
82            test.err.as_ref(),
83            "Test case {}: Expected error containing '{:?}', got '{:?}'",
84            i,
85            test.err,
86            err
87          );
88        }
89        (Ok(out), None) => {
90          panic!(
91            "Test case {}: Expected error '{:?}', got success: {:?}",
92            i, test.err, out
93          );
94        }
95        (Err(err), Some(expected)) => {
96          panic!(
97            "Test case {}: Expected {:?}, got error: {:?}",
98            i, expected, err
99          );
100        }
101      }
102    }
103  }
104
105  #[test]
106  fn test_default() {
107    let addr = InfiniBandAddr::default();
108    assert_eq!(addr.octets(), [0; INFINI_BAND_ADDRESS_SIZE]);
109  }
110
111  #[test]
112  fn formatted() {
113    let addr =
114      InfiniBandAddr::try_from("00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01")
115        .unwrap();
116    assert_eq!(
117      addr.to_string(),
118      "00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01"
119    );
120    assert_eq!(
121      addr.to_colon_separated(),
122      "00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01"
123    );
124
125    let dot = addr.to_dot_separated_array();
126    let dot_str = core::str::from_utf8(&dot).unwrap();
127    assert_eq!(dot_str, "0000.0000.fe80.0000.0000.0000.0200.5e10.0000.0001");
128    assert_eq!(
129      addr.to_dot_separated(),
130      "0000.0000.fe80.0000.0000.0000.0200.5e10.0000.0001"
131    );
132
133    let dashed = addr.to_hyphen_separated_array();
134    let dashed_str = core::str::from_utf8(&dashed).unwrap();
135    assert_eq!(
136      dashed_str,
137      "00-00-00-00-fe-80-00-00-00-00-00-00-02-00-5e-10-00-00-00-01"
138    );
139    assert_eq!(
140      addr.to_hyphen_separated(),
141      "00-00-00-00-fe-80-00-00-00-00-00-00-02-00-5e-10-00-00-00-01"
142    );
143  }
144
145  #[cfg(feature = "serde")]
146  #[test]
147  fn serde_human_readable() {
148    let addr =
149      InfiniBandAddr::try_from("00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01")
150        .unwrap();
151    let json = serde_json::to_string(&addr).unwrap();
152    assert_eq!(
153      json,
154      "\"00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01\""
155    );
156
157    let addr2: InfiniBandAddr = serde_json::from_str(&json).unwrap();
158    assert_eq!(addr, addr2);
159  }
160
161  #[cfg(feature = "serde")]
162  #[test]
163  fn serde_human_unreadable() {
164    let addr =
165      InfiniBandAddr::try_from("00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01")
166        .unwrap();
167    let encoded = bincode::serde::encode_to_vec(addr, bincode::config::standard()).unwrap();
168    assert_eq!(
169      encoded,
170      [
171        0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x5e,
172        0x10, 0x00, 0x00, 0x00, 0x01,
173      ]
174    );
175    assert_eq!(addr.octets(), encoded.as_slice());
176
177    let addr2: InfiniBandAddr =
178      bincode::serde::decode_from_slice(&encoded, bincode::config::standard())
179        .unwrap()
180        .0;
181    assert_eq!(addr, addr2);
182    let addr3 = InfiniBandAddr::from_raw([
183      0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x5e,
184      0x10, 0x00, 0x00, 0x00, 0x01,
185    ]);
186    assert_eq!(addr, addr3);
187    println!("{:?}", addr);
188  }
189}