How to allow extra commas in macros?

Here is a synthetic example of what I want:

macro_rules! define_enum { ($Name:ident { $($Variant:ident),* }) => { pub enum $Name { None, $($Variant),*, } } } define_enum!(Foo { A, B }); 

This code compiles, but if you add a comma to it:

 define_enum!(Foo { A, B, }); // ^ 

Fail compilation. I can fix it with

 ($Name:ident { $($Variant:ident,)* }) // ^ 

but then define_enum!(Foo { A, B }); out of order

How to write a macro to handle both cases:

 define_enum!(Foo { A, B }); define_enum!(Foo { A, B, }); 
+7
macros rust
source share
1 answer

You can handle both cases with ... handling both cases:

 macro_rules! define_enum { ($Name:ident { $($Variant:ident,)* }) => { pub enum $Name { None, $($Variant),*, } }; ($Name:ident { $($Variant:ident),* }) => { define_enum!($Name { $($Variant,)* }); }; } define_enum!(Foo1 { A, B }); define_enum!(Foo2 { A, B, }); fn main() {} 

We moved the main version to the version that expects the final comma. Then we added a second sentence, which corresponds to the case with a missing comma and overwrites it with a comma version.


DK. indicates an alternative , making the trailing comma optional:

 ($Name:ident { $($Variant:ident),* $(,)* }) => { 

This avoids the need for delegation from one implementation to another.

In the nightly versions of Rust, you can use the macro_at_most_once_rep function to record this in a more obvious way and to disable several trailing commas:

 ($Name:ident { $($Variant:ident),* $(,)? }) => { // ^ 
+12
source share

All Articles