macro_rules! verify_pred {
($expr:expr $(,)?) => { ... };
}
Expand description
Asserts that the given predicate applied to the given arguments returns true.
Similarly to verify_that
, this evaluates to a Result
whose Ok
variant indicates that the given predicate returned true and whose Err
variant indicates that it returned false.
The failure message contains detailed information about the arguments. For example:
fn equals_modulo(a: i32, b: i32, n: i32) -> bool { a % n == b % n }
#[test]
fn test() -> Result<()> {
let a = 1;
fn b(_x: i32) -> i32 { 7 }
verify_pred!(equals_modulo(a, b(b(2)), 2 + 3))?;
Ok(())
}
This results in the following message:
equals_modulo(a, b(b(2)), 2 + 3) was false with
a = 1,
b(b(2)) = 7,
2 + 3 = 5,
The predicate can also be a method on a struct, e.g.:
struct AStruct {};
impl AStruct {
fn equals_modulo(...) {...}
}
verify_pred!((AStruct {}).equals_modulo(a, b, n))?;
The expression passed to this macro must return bool
. In the most general
case, it prints out each of the .
-separated parts of the expression and
the arguments of all top-level method calls as long as they implement
Debug
. It evaluates every value (including the method receivers) exactly
once. Effectively, for verify_pred!((a + 1).b.c(x + y, &mut z, 2))
, it
generates code analogous to the following, which allows printing accurate
intermediate values even if they are subsequently consumed (moved out) or
mutated in-place by the expression:
let mut error_message = "(a + 1).b.c(x + y, 2) was false with".to_string();
let mut x1 = (a + 1);
write!(error_message, "\n (a + 1) = {:?},", x1);
write!(error_message, "\n (a + 1).b = {:?},", x1.b);
let mut x2 = x + y;
write!(error_message, "\n x + y = {:?},", x2);
let mut x3 = &mut z;
write!(error_message, "\n & mut z = {:?},", x3);
let mut x4 = x1.b.c(x2, x3, 2);
if (x4) {
Ok(())
} else {
Err(error_message)
}
Wrapping the passed-in expression in parens or curly braces will prevent the detailed printing of the expression.
verify_pred!((a.foo()).bar())?;
would not print a
, but would print (a.foo())
and (a.foo()).bar()
on
error.