hardware_address/
infini_band.rs

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