| 1 | //! Inspect Macros |
|---|---|
| 2 | |
| 3 | /// Evaluates an expression, prints a stringified version of the expression |
| 4 | /// along with the evaluated value, and then returns that value. |
| 5 | /// |
| 6 | /// # Example |
| 7 | /// |
| 8 | /// ``` |
| 9 | /// # #[macro_use] extern crate mac; |
| 10 | /// |
| 11 | /// # fn main() { |
| 12 | /// fn lcm_2_to_4() -> u32 { |
| 13 | /// let mut i = 1; |
| 14 | /// loop { |
| 15 | /// if inspect!(i % 2, i % 3, i % 4) == (0, 0, 0) { |
| 16 | /// return inspect!("done: i = "=> i); |
| 17 | /// } |
| 18 | /// i += 1; |
| 19 | /// } |
| 20 | /// } |
| 21 | /// assert_eq!(lcm_2_to_4(), 12); |
| 22 | /// # } |
| 23 | /// ``` |
| 24 | /// |
| 25 | /// Returns `12`, and prints the following to stdout: |
| 26 | /// |
| 27 | /// ```ignore |
| 28 | /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 1, 1) |
| 29 | /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 2, 2) |
| 30 | /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 0, 3) |
| 31 | /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 1, 0) |
| 32 | /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 2, 1) |
| 33 | /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 0, 2) |
| 34 | /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 1, 3) |
| 35 | /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 2, 0) |
| 36 | /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 0, 1) |
| 37 | /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 1, 2) |
| 38 | /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 2, 3) |
| 39 | /// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 0, 0) |
| 40 | /// src/inspect.rs:95 - done: i = 12 |
| 41 | /// ``` |
| 42 | |
| 43 | #[macro_export] |
| 44 | macro_rules! inspect { |
| 45 | ($prefix:expr => $expr:expr) => {{ |
| 46 | let val = $expr; |
| 47 | println!("{}:{} - {}{:?}", file!(), line!(), $prefix, val); |
| 48 | val |
| 49 | }}; |
| 50 | ($expr:expr) => { |
| 51 | inspect!(concat!(stringify!($expr), " = ") => $expr) |
| 52 | }; |
| 53 | ($prefix:expr => $($expr:expr),+) => { |
| 54 | inspect!($prefix => ($($expr),+)) |
| 55 | }; |
| 56 | ($($expr:expr),+) => { |
| 57 | inspect!(($($expr),+)) |
| 58 | }; |
| 59 | } |
| 60 | |
| 61 | #[test] |
| 62 | fn test_inspect() { |
| 63 | assert_eq!(inspect!("foo"), "foo"); |
| 64 | assert_eq!(inspect!(""=> "foo"), "foo"); |
| 65 | assert_eq!(inspect!(1 + 2, 2 + 3, 3 + 4), (3, 5, 7)); |
| 66 | assert_eq!(inspect!(""=> 1 + 2, 2 + 3, 3 + 4), (3, 5, 7)); |
| 67 | |
| 68 | fn fib(n: u64) -> u64 { |
| 69 | inspect!("fib :: n = "=> n); |
| 70 | inspect! { "ret = "=> match n { |
| 71 | 0 | 1 => n, |
| 72 | n => fib(n-1) + fib(n-2) |
| 73 | }} |
| 74 | } |
| 75 | |
| 76 | fn fib_iter(n: u64) -> u64 { |
| 77 | inspect!("fib_iter :: n = "=> n); |
| 78 | let (mut a, mut b) = (0, 1); |
| 79 | for _ in 0..n { |
| 80 | inspect!(a, b); |
| 81 | let tmp = b; |
| 82 | b += a; |
| 83 | a = tmp; |
| 84 | } |
| 85 | inspect!("ret = "=> a) |
| 86 | } |
| 87 | |
| 88 | assert_eq!(fib(4), 3); |
| 89 | assert_eq!(fib_iter(7), 13); |
| 90 | |
| 91 | // Uncomment the following to see the output in `cargo test`. |
| 92 | // panic!() |
| 93 | } |
| 94 |
Definitions
Learn Rust with the experts
Find out more
