// Rules are tried top to bottom and the first whose matcher matches wins, so // their order is semantics rather than style. That is also what makes a // recursive macro terminate: a base-case rule sits above the recursive one. macro_rules! describe { () => { 0 }; ($x:expr) => { $x }; ($x:expr, $y:expr) => { $x * 100 + $y }; } // Recursion, shedding one argument per step. macro_rules! total { () => { 0 }; ($x:expr) => { $x }; ($x:expr, $($rest:expr),+) => { $x + total!($($rest),+) }; } macro_rules! depth { ($x:expr) => { 1 }; ($x:expr, $($rest:expr),+) => { 1 + depth!($($rest),+) }; } // Different shapes, not just different arities. macro_rules! pick { (first $a:expr, $b:expr) => { $a }; (second $a:expr, $b:expr) => { $b }; (sum $a:expr, $b:expr) => { $a + $b }; } fn main() { println!("{} {} {}", describe!(), describe!(7), describe!(3, 4)); println!("{}", total!()); println!("{}", total!(5)); println!("{}", total!(1, 2, 3, 4, 5)); println!("{}", total!(2 * 3, 4 + 1)); println!("{} {}", depth!(9), depth!(9, 9, 9, 9)); println!("{} {} {}", pick!(first 10, 20), pick!(second 10, 20), pick!(sum 10, 20)); let a: i64 = 1000; println!("{}", total!(a, a, a)); }