Reputation: 3271
I have a macro that simplifies the parsing of enums from strings in the form:
enum_printer!(Bar { fun1["AB","CD"]; fun2[] });
To make it slightly easier to use, I would like to make the []
optional i.e. be able to specify
enum_printer!(Bar { fun1["AB","CD"]; fun2; fun3 });
Here's the code as it stands
use failure::Error;
use std::convert::TryFrom;
macro_rules! enum_printer {
($name:ident { $($enumeration:ident [$($v:expr),*]);* }) => {
#[derive(Debug)]
enum $name {
$(
$enumeration,
)*
}
impl<'a> TryFrom<&'a str> for $name {
type Error = Error;
fn try_from(value : &'a str) -> Result<$name,Error> {
match value {
$(
stringify!($enumeration)
$(
| $v
)*
=> Ok($name::$enumeration),
)*
_ => Err(err_msg("Could not convert from string to"))
}
}
}
};
}
I've attempted to modify the first line:
($name:ident { $($enumeration:ident [$($v:expr),*]?);* }) => {
error: no rules expected the token `;`
--> src/main.rs:30:36
|
30 | enum_printer!(Bar { fun1["AB","CD"]; fun2; fun3 });
| ^
Is there a way to achieve this?
Upvotes: 5
Views: 1181
Reputation: 42849
The syntax for the ?
is the same as one for *
or +
: you must surround the optional pattern like this $( <pattern> )?
.
Example:
#![feature(macro_at_most_once_rep)]
macro_rules! foo {
( $( $e:expr )? ) => {
$( $e )?
}
}
In your example, you must write:
($name:ident {
$(
$enumeration:ident $(
[$( $v:expr ),*]
)? // optional parameter
);* // possible multiple parameters
}) => {
(I split the line to be clearer)
Upvotes: 4