// Group functionality with different types // Define special syntac for specific purpose // Variable number of arguments // Different combination of arguments macro_rules! say_hello { () => { println!("Hello world!"); }; } // Types of arguments have designators: // block // expr is used for expressions // ident is used for variable/function names // item // literal is used for literal constants // pat (pattern) // path // stmt (statement) // tt (token tree) // ty (type) // vis (visibility qualifier) macro_rules! generate_function { ($func_name:ident) => { fn $func_name() { println!("You called {:?}()", stringify!($func_name)); } }; } generate_function!(foo); macro_rules! process_expression { ($expression: expr) => { println!("{:?} = {:?}", stringify!($expression), $expression); }; } // Overload macro_rules! match_block { ($left: expr; and $right: expr) => { println!("A: {:?} and {:?}", stringify!($left), stringify!($right)) }; ($left: expr; or $right:expr) => { println!( "B: {:?} or {:?} is {:?}", stringify!($left), stringify!($right), $left || $right ) }; } // Repeat: variable number of args o a type macro_rules! find_max { ($x:expr) => ($x); ($x:expr, $($y:expr), +) => (std::cmp::max($x, find_max!($($y), +))); } // DSLs: Domain Specific Languages // macro_rules allows you to create your own syntax macro_rules! calc { (eval $e:expr) => { println!("{} = {}", stringify!($e), $e); }; } macro_rules! calculate { (eval $e: expr) => { { let val: usize = $e; // Force types to be integers println!("{} = {}", stringify!{$e}, val); } }; (eval $e: expr, $(eval $y: expr), +) => {{ calculate!{eval $e} calculate!{ $(eval $y), + } }}; } pub fn macros_rule() { foo(); say_hello!(); process_expression!(1 + 5 * 3); match_block!(1i32 + 1 == 2i32; and 2i32 * 2 == 4i32); // Enters first branch match_block!(true; or false); // Enter second branch match_block!(true; and true); // Enters first branch println!("Max is {}", find_max!(5, 3 * 8, 4, 9 * 5)); calc! { eval (1 + 2) * 4 } calculate! { eval (1 + 2) * 4, eval 1 + 5, eval 7 + 4, eval 3 + 9 } }