How to allow optional trailing commas in macros?

Change the line

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

to

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

to add an optional comma at the end. This works in stable Rust / 2018 edition. This syntax also works for other separators like a semicolon.


Handle both cases

You can handle both cases by... 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've moved the main implementation to the version that expects the trailing comma. We then added a second clause that matches the case with the missing comma and rewrites it to the version with a comma.

Make the comma optional

DK. points out an alternative, making the trailing comma itself optional.

This avoids the need to delegate from one implementation to the other.

Rust 1.32

You can use the ? macro repeater to write this and disallow multiple trailing commas:

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

Previous versions

This allows multiple trailing commas:

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

Tags:

Macros

Rust