Given a variable number of arguments in a Rust macro (i.e., $($varargs:pat),*
), I want to print them nicely delimited.
For example, given a macro something!
that takes a variable number of arguments, e.g. something!(a, b, c)
, I want to print them in a string: "a, b, c"
.
I could not find any resources online for this, so putting it out into the world in case this helps someone else. Other answers appreciated.
macro_rules! something {
($($varargs:pat),* $(,)?) => {
println!("{}", something!(@stringify_varargs $($varargs),*));
};
(@stringify_varargs $($varargs:pat),*) => {
{
vec![$(format!("{}", stringify!($varargs))),*].join(", ")
}
};
}
fn main() {
let a = 1;
let b = 2;
let c = 3;
something!(a, b, c);
}
macro_rules! something {
($($varargs:pat),* $(,)?) => {
println!("{}", something!(@stringify_varargs $($varargs),*));
};
(@stringify_varargs $($varargs:pat),*) => {
{
let mut patterns = String::new();
$(
patterns.push_str(&format!("{}, ", stringify!($varargs)));
)*
// Remove the trailing comma
let _ = patterns.truncate(patterns.len() - 2);
patterns
}
};
}
fn main() {
let a = 1;
let b = 2;
let c = 3;
something!(a, b, c);
}
macro_rules! something {
($($varargs:pat),* $(,)?) => {
println!("{}", something!(@stringify_varargs $($varargs),*));
};
(@stringify_varargs $($expected:pat),*) => {
something!(@stringify_varargs_helper $($expected),*)
};
(@stringify_varargs_helper $first:pat, $($rest:pat),*) => {
concat!(stringify!($first), $(", ", stringify!($rest)),*)
};
(@stringify_varargs_helper $last:pat) => {
// Do not print last comma
stringify!($last)
};
}
fn main() {
let a = 1;
let b = 2;
let c = 3;
something!(a, b, c);
}