我有一个宏,它简化了以下形式的字符串解析枚举:
enum_printer!(Bar { fun1["AB","CD"]; fun2[] });
为了使其更容易使用,我想使[]
可选,即能够指定
enum_printer!(Bar { fun1["AB","CD"]; fun2; fun3 });
这里是代码
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"))
}
}
}
};
}
我试图修改第一行:
($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 });
| ^
有没有办法实现这个目标?
答案 0 :(得分:2)
?
的语法与*
或+
的语法相同:您必须包围可选模式,如$( <pattern> )?
。
示例:
#![feature(macro_at_most_once_rep)]
macro_rules! foo {
( $( $e:expr )? ) => {
$( $e )?
}
}
在您的示例中,您必须写:
($name:ident {
$(
$enumeration:ident $(
[$( $v:expr ),*]
)? // optional parameter
);* // possible multiple parameters
}) => {
(我把这条线拆分得更清楚了)