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
//! Inspect Macros
/// Evaluates an expression, prints a stringified version of the expression
/// along with the evaluated value, and then returns that value.
///
/// # Example
///
/// ```
/// # #[macro_use] extern crate mac;
///
/// # fn main() {
/// fn lcm_2_to_4() -> u32 {
/// let mut i = 1;
/// loop {
/// if inspect!(i % 2, i % 3, i % 4) == (0, 0, 0) {
/// return inspect!("done: i = " => i);
/// }
/// i += 1;
/// }
/// }
/// assert_eq!(lcm_2_to_4(), 12);
/// # }
/// ```
///
/// Returns `12`, and prints the following to stdout:
///
/// ```ignore
/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 1, 1)
/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 2, 2)
/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 0, 3)
/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 1, 0)
/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 2, 1)
/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 0, 2)
/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 1, 3)
/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 2, 0)
/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 0, 1)
/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 1, 2)
/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 2, 3)
/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 0, 0)
/// src/inspect.rs:95 - done: i = 12
/// ```
#[macro_export]
macro_rules! inspect {
($prefix:expr => $expr:expr) => {{
let val = $expr;
println!("{}:{} - {}{:?}", file!(), line!(), $prefix, val);
val
}};
($expr:expr) => {
inspect!(concat!(stringify!($expr), " = ") => $expr)
};
($prefix:expr => $($expr:expr),+) => {
inspect!($prefix => ($($expr),+))
};
($($expr:expr),+) => {
inspect!(($($expr),+))
};
}
#[test]
fn test_inspect() {
assert_eq!(inspect!("foo"), "foo");
assert_eq!(inspect!("" => "foo"), "foo");
assert_eq!(inspect!(1 + 2, 2 + 3, 3 + 4), (3, 5, 7));
assert_eq!(inspect!("" => 1 + 2, 2 + 3, 3 + 4), (3, 5, 7));
fn fib(n: u64) -> u64 {
inspect!("fib :: n = " => n);
inspect! { "ret = " => match n {
0 | 1 => n,
n => fib(n-1) + fib(n-2)
}}
}
fn fib_iter(n: u64) -> u64 {
inspect!("fib_iter :: n = " => n);
let (mut a, mut b) = (0, 1);
for _ in 0..n {
inspect!(a, b);
let tmp = b;
b += a;
a = tmp;
}
inspect!("ret = " => a)
}
assert_eq!(fib(4), 3);
assert_eq!(fib_iter(7), 13);
// Uncomment the following to see the output in `cargo test`.
// panic!()
}