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
/// Assert an expression is not equal to an expression.
///
/// * If true, return Result `Ok(())`.
///
/// * When false, return [`Err`] with a message and the values of the
/// expressions with their debug representations.
///
/// This macro provides the same statements as [`assert_`],
/// except this macro returns a Result, rather than doing a panic.
///
/// This macro is useful for runtime checks, such as checking parameters,
/// or santizing inputs, or handling different results in different ways.
///
/// # Related
///
/// * [`assert_ne`]
/// * [`assert_ne_as_result`]
/// * [`debug_assert_ne`]
///
#[macro_export]
macro_rules! assert_ne_as_result {
($a:expr, $b:expr $(,)?) => ({
match (&$a, &$b) {
(a_val, b_val) => {
if a_val != b_val {
Ok(())
} else {
Err(format!(
concat!(
"assertion failed: `assert_ne!(left, right)`\n",
" left label: `{}`,\n",
" left debug: `{:?}`,\n",
" right label: `{}`,\n",
" right debug: `{:?}`,\n",
" left: `{:?}`,\n",
" right: `{:?}`"
),
stringify!($a), $a,
stringify!($b), $b,
a_val,
b_val
))
}
}
}
});
}
#[cfg(test)]
mod tests {
#[test]
fn test_assert_ne_as_result_x_success() {
let a: i32 = 1;
let b: i32 = 2;
let x = assert_ne_as_result!(a, b);
assert_eq!(x, Ok(()));
}
#[test]
fn test_assert_ne_as_result_x_failure() {
let a: i32 = 1;
let b: i32 = 1;
let x = assert_ne_as_result!(a, b);
assert!(x.is_err());
assert_eq!(
x.unwrap_err(),
concat!(
"assertion failed: `assert_ne!(left, right)`\n",
" left label: `a`,\n",
" left debug: `1`,\n",
" right label: `b`,\n",
" right debug: `1`,\n",
" left: `1`,\n",
" right: `1`"
)
);
}
}
/// Assert an expression is not equal to an expression.
///
/// This macro provides the same statements as [`assert_ne`],
/// except this macro's statements are only enabled in non-optimized
/// builds by default. An optimized build will not execute this macro's
/// statements unless `-C debug-assertions` is passed to the compiler.
///
/// This macro is useful for checks that are too expensive to be present
/// in a release build but may be helpful during development.
///
/// The result of expanding this macro is always type checked.
///
/// An unchecked assertion allows a program in an inconsistent state to
/// keep running, which might have unexpected consequences but does not
/// introduce unsafety as long as this only happens in safe code. The
/// performance cost of assertions, however, is not measurable in general.
/// Replacing `assert*!` with `debug_assert*!` is thus only encouraged
/// after thorough profiling, and more importantly, only in safe code!
///
/// This macro is intendend to work in a similar way to
/// [`std::debug_assert`](https://doc.rust-lang.org/std/macro.debug_assert.html).
///
/// # Related
///
/// * [`assert_ne`]
/// * [`assert_ne`]
/// * [`debug_assert_ne`]
///
#[macro_export]
macro_rules! debug_assert_ne {
($($arg:tt)*) => {
if $crate::cfg!(debug_assertions) {
$crate::assert_ne!($($arg)*);
}
};
}