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 | |