snippetrustMajor
How to allow optional trailing commas in macros?
Viewed 0 times
macroshowtrailingcommasallowoptional
Problem
Here's a synthetic example of what I want:
This code compiles, but if add a comma to it:
The compilation fails. I can fix it with:
but then
How should I write a macro to handle both cases:
macro_rules! define_enum {
($Name:ident { $($Variant:ident),* }) => {
pub enum $Name {
None,
$($Variant),*,
}
}
}
define_enum!(Foo { A, B });This code compiles, but if add a comma to it:
define_enum!(Foo { A, B, });
// ^The compilation fails. I can fix it with:
($Name:ident { $($Variant:ident,)* })
// ^but then
define_enum!(Foo { A, B }); fails,How should I write a macro to handle both cases:
define_enum!(Foo { A, B });
define_enum!(Foo { A, B, });Solution
Make the comma optional
As DK. points out, the trailing comma can be made optional.
Rust 1.32
You can use the
Previous versions
This allows multiple trailing commas:
Handle both cases
Or you can handle both cases by... handling both cases:
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.
As DK. points out, the trailing comma can be made optional.
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), $(,) }) => {
// ^^^^^
Handle both cases
Or 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.
Code Snippets
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() {}Context
Stack Overflow Q#43143327, score: 99
Revisions (0)
No revisions yet.