1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//! # Assert Hex
//!
//! Writing and testing protocol level libraries requires many tests to be written
//! with respect to protocol sections in hex. This library simplifies the process
//! of viewing the differences between numbers in hex when tests fail.
//!
//! # Usage
//!
//! Replace `assert_eq` or `assert_ne` with `assert_eq_hex` or `assert_ne_hex`
//! respectively.

/// Asserts that two expressions are equal to each other
///
/// On panic, this macro will print values of the expressions in their
/// hex representation
#[macro_export]
macro_rules! assert_eq_hex {
    ($left:expr, $right:expr) => ({
        match (&$left, &$right) {
            (left_val, right_val) => {
                if !(*left_val == *right_val) {
                    // The reborrows below are intentional. Without them, the stack slot for the
                    // borrow is initialized even before the values are compared, leading to a
                    // noticeable slow down.
                    panic!(r#"assertion failed: `(left == right)`
  left: `0x{:02x?}`,
 right: `0x{:02x?}`"#, &*left_val, &*right_val)
                }
            }
        }
    });
    ($left:expr, $right:expr,) => ({
        $crate::assert_eq!($left, $right)
    });
    ($left:expr, $right:expr, $($arg:tt)+) => ({
        match (&($left), &($right)) {
            (left_val, right_val) => {
                if !(*left_val == *right_val) {
                    // The reborrows below are intentional. Without them, the stack slot for the
                    // borrow is initialized even before the values are compared, leading to a
                    // noticeable slow down.
                    panic!(r#"assertion failed: `(left == right)`
  left: `0x{:02x?}`,
 right: `0x{:02x?}`: {}"#, &*left_val, &*right_val,
                           $crate::format_args!($($arg)+))
                }
            }
        }
    });
}

/// Asserts that two expressions are not equal to each other
///
/// On panic, this macro will print values of the expressions in their
/// hex representation
#[macro_export]
macro_rules! assert_ne_hex {
    ($left:expr, $right:expr) => ({
        match (&$left, &$right) {
            (left_val, right_val) => {
                if *left_val == *right_val {
                    // The reborrows below are intentional. Without them, the stack slot for the
                    // borrow is initialized even before the values are compared, leading to a
                    // noticeable slow down.
                    panic!(r#"assertion failed: `(left != right)`
  left: `0x{:02x?}`,
 right: `0x{:02x?}`"#, &*left_val, &*right_val)
                }
            }
        }
    });
    ($left:expr, $right:expr,) => {
        $crate::assert_ne!($left, $right)
    };
    ($left:expr, $right:expr, $($arg:tt)+) => ({
        match (&($left), &($right)) {
            (left_val, right_val) => {
                if *left_val == *right_val {
                    // The reborrows below are intentional. Without them, the stack slot for the
                    // borrow is initialized even before the values are compared, leading to a
                    // noticeable slow down.
                    panic!(r#"assertion failed: `(left != right)`
  left: `0x{:02x?}`,
 right: `0x{:02x?}`: {}"#, &*left_val, &*right_val,
                           $crate::format_args!($($arg)+))
                }
            }
        }
    });
}

#[cfg(test)]
mod tests {
    use crate::{assert_eq_hex, assert_ne_hex};

    #[test]
    #[should_panic(expected = r#"assertion failed: `(left == right)`
  left: `0x50`,
 right: `0x46`"#)]
    fn test_eq_0() {
        assert_eq_hex!(0x50, 0x46);
    }

    #[test]
    #[should_panic(expected = r#"assertion failed: `(left == right)`
  left: `0xff`,
 right: `0x46`"#)]
    fn test_eq_1() {
        assert_eq_hex!(0xff, 0x46);
    }

    #[test]
    #[should_panic(expected = r#"assertion failed: `(left == right)`
  left: `0xff`,
 right: `0x46`"#)]
    fn test_eq_2() {
        assert_eq_hex!(0xff, 0x46);
    }

    #[test]
    #[should_panic(expected = r#"assertion failed: `(left == right)`
  left: `0x[00, 01, 02]`,
 right: `0x[46, 50, 40]`"#)]
    fn test_eq_3() {
        assert_eq_hex!(vec!(0x00, 0x01, 0x02), vec!(0x46, 0x50, 0x40));
    }

    #[test]
    #[should_panic(expected = r#"assertion failed: `(left != right)`
  left: `0x50`,
 right: `0x50`"#)]
    fn test_ne_0() {
        assert_ne_hex!(0x50, 0x50);
    }

    #[test]
    #[should_panic(expected = r#"assertion failed: `(left != right)`
  left: `0xff`,
 right: `0xff`"#)]
    fn test_ne_1() {
        assert_ne_hex!(0xff, 0xff);
    }
}