In a Rust `macro_rules!` macro, repetition lets one rule accept a variable number of inputs. Put the part to repeat inside `$()`, then choose an operator: `*` means zero or more times, `+` means one or more, and `?` means zero or one. A separator, such as a comma, goes between the closing parenthesis and the operator: `$($input:tt),*`. section 22.2 section 22.3
macro_rules! print_anything {
($($input1:tt),*) => {
let output = stringify!($($input1),*);
println!("{}", output);
};
}
fn main() {
print_anything!(ththdoetd, rcofe);
print_anything!();
print_anything!(87575oehq75onth, ntohe, 987987o, 097);
}
`print_anything!` accepts comma-separated token trees and also accepts an empty call. Its expansion repeats those inputs inside `stringify!`. section 22.2
Choose `+` when an empty call should not match. For example, `$($input:tt),+` requires at least one token tree. The separator is part of the rule: changing its comma to a semicolon means calls must use semicolons too. section 22.2
An optional trailing comma
In `$(,)?`, the repeated part is just a comma. It can appear once or not at all. The `matches!` rule uses it to accept a trailing comma; a separate `$(if $guard:expr)?` makes a match guard optional. section 22.3
macro_rules! make_a_function {
($name:ident, $($input:tt),+) => { #1
fn $name() {
let output = stringify!($($input),+); #2
println!("{}", output);
}
};
}
fn main() {
make_a_function!(print_it, 5, 5, 6, I); #3
print_it();
make_a_function!(say_its_nice, this, is, really, nice); #4
say_its_nice();
}
`make_a_function!` combines one required function name with one-or-more comma-separated token trees, then repeats the inputs in the generated function. section 22.2

