枚举解析
macro_rules! parse_unitary_variants {
(@as_expr $e:expr) => {$e};
(@as_item $($i:item)+) => {$($i)+};
// Exit rules.
(
@collect_unitary_variants ($callback:ident ( $($args:tt)* )),
($(,)*) -> ($($var_names:ident,)*)
) => {
parse_unitary_variants! {
@as_expr
$callback!{ $($args)* ($($var_names),*) }
}
};
(
@collect_unitary_variants ($callback:ident { $($args:tt)* }),
($(,)*) -> ($($var_names:ident,)*)
) => {
parse_unitary_variants! {
@as_item
$callback!{ $($args)* ($($var_names),*) }
}
};
// Consume an attribute.
(
@collect_unitary_variants $fixed:tt,
(#[$_attr:meta] $($tail:tt)*) -> ($($var_names:tt)*)
) => {
parse_unitary_variants! {
@collect_unitary_variants $fixed,
($($tail)*) -> ($($var_names)*)
}
};
// Handle a variant, optionally with an with initialiser.
(
@collect_unitary_variants $fixed:tt,
($var:ident $(= $_val:expr)*, $($tail:tt)*) -> ($($var_names:tt)*)
) => {
parse_unitary_variants! {
@collect_unitary_variants $fixed,
($($tail)*) -> ($($var_names)* $var,)
}
};
// Abort on variant with a payload.
(
@collect_unitary_variants $fixed:tt,
($var:ident $_struct:tt, $($tail:tt)*) -> ($($var_names:tt)*)
) => {
const _error: () = "cannot parse unitary variants from enum with non-unitary variants";
};
// Entry rule.
(enum $name:ident {$($body:tt)*} => $callback:ident $arg:tt) => {
parse_unitary_variants! {
@collect_unitary_variants
($callback $arg), ($($body)*,) -> ()
}
};
}
#
# fn main() {
# assert_eq!(
# parse_unitary_variants!(
# enum Dummy { A, B, C }
# => stringify(variants:)
# ),
# "variants : ( A , B , C )"
# );
# }
此宏展示了如何使用标记树撕咬机与下推累积来解析类C枚举的变量。完成后的parse_unitary_variants!
宏将调用一个回调宏,为后者提供枚举中的所有选择(以及任何附加参数)。
经过改造后,此宏将也能用于解析struct
的域,或为枚举变量计算标签值,甚至是将任意一个枚举中的所有变量名称都提取出来。
当前内容版权归 DaseinPhaos 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 DaseinPhaos .