Line data Source code
1 : /// Useful type for asserting that expected bytes match reporting the bytes more readable
2 : /// array-syntax compatible hex bytes.
3 : ///
4 : /// # Usage
5 : ///
6 : /// ```
7 : /// use utils::Hex;
8 : ///
9 : /// let actual = serialize_something();
10 : /// let expected = [0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64];
11 : ///
12 : /// // the type implements PartialEq and on mismatch, both sides are printed in 16 wide multiline
13 : /// // output suffixed with an array style length for easier comparisons.
14 : /// assert_eq!(Hex(&actual), Hex(&expected));
15 : ///
16 : /// // with `let expected = [0x68];` the error would had been:
17 : /// // assertion `left == right` failed
18 : /// // left: [0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64; 11]
19 : /// // right: [0x68; 1]
20 : /// # fn serialize_something() -> Vec<u8> { "hello world".as_bytes().to_vec() }
21 : /// ```
22 : pub struct Hex<S>(pub S);
23 :
24 : impl<S: AsRef<[u8]>> std::fmt::Debug for Hex<S> {
25 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 0 : write!(f, "[")?;
27 0 : let chunks = self.0.as_ref().chunks(16);
28 0 : for (i, c) in chunks.enumerate() {
29 0 : if i > 0 && !c.is_empty() {
30 0 : writeln!(f, ", ")?;
31 0 : }
32 0 : for (j, b) in c.iter().enumerate() {
33 0 : if j > 0 {
34 0 : write!(f, ", ")?;
35 0 : }
36 0 : write!(f, "0x{b:02x}")?;
37 : }
38 : }
39 0 : write!(f, "; {}]", self.0.as_ref().len())
40 0 : }
41 : }
42 :
43 : impl<R: AsRef<[u8]>, L: AsRef<[u8]>> PartialEq<Hex<R>> for Hex<L> {
44 140 : fn eq(&self, other: &Hex<R>) -> bool {
45 140 : let left = self.0.as_ref();
46 140 : let right = other.0.as_ref();
47 140 :
48 140 : left == right
49 140 : }
50 : }
|