In effect, I'd like to be able to write a macro something like this:
example! {
"hello",
Apple = "banana",
Cherry = "danish",
Eclaire,
}
In other words, a mixture of "expr" forms or "name = expr" forms. A macro like this can be implemented using an Incremental TT Muncher; for example:
macro_rules! example {
($name:ident = $value:expr, $($tts:tt)*) => {
example!($($tts)*)
};
($value:expr, $($tts:tt)*) => {
example!($($tts)*)
};
() => {}
}
However, if I understand correctly, a macro of this form can't allow for any trailing tokens following the TokenTree repetition, so "natural" code forms like this aren't possible with this implementation:
example!("a", b = 1)
In theory, we might try matching an optional comma following a TokenTree repetition, but that fails:
error: local ambiguity when calling macro
example
: multiple parsing options: built-in NTs tt ('tts') or 1 other option
And this also implies that other approaches that might try to adjust where the comma is consumed in the macro are effectively doomed to fail.
Is there a way forward that I'm missing, or some reasonable extension that could be proposed which the Rust team might consider including?
For what it's worth, I could imagine something like "lazy" repetitions using *?
, where something like:
($($tts:tt)*? $(,)?) => { ... }
would allow a final (optional) comma to be matched separately from the TokenTree repetition, but I'm not sure how much extra complexity this would introduce into the macro engine. (Maybe it's okay as long as we allow only a single repetition of this form?)