我正在尝试在Rust中编写一个相当复杂的宏。以下是宏在外面看起来的样子:
supported_messages![
OpenSecureChannelRequest,
OpenSecureChannelResponse,
CloseSecureChannelRequest,
CloseSecureChannelResponse,
// This list will eventually have 100s of values
];
在内部,它将每个id扩展为类似的东西(以及许多其他锅炉板):
ObjectId::Foo_Encoding_DefaultBinary => { SupportedMessage::Foo(Foo::decode()?) },
这个伪宏提供了我正在做的事情的要点:
macro_rules! supported_messages {
[ $( $x:ident ), * ] => {
$( ObjectId::$x_Encoding_DefaultBinary => {
SupportedMessage::$x($x::decode()?)
}, )*
}
完整的宏和来源在线,可以看到here。
宏采用一组id,并且每个id都会喷出一组匹配模式,类似于上面的例子。
我无法使用标识符$x
,例如Foo
并将其转换为新的标识符Foo_Encoding_DefaultBinary
。
Rust有一个concat_idents!()
,但是根据我的阅读,它几乎没用,而且已被弃用了。还有另外一种方法吗?程序宏尚未在稳定编译器上可用,也可能不易使用。
目前,我正在自动生成大部分其他样板,但必须手动编写上面的代码。这很乏味。
有办法做到这一点吗?
在C中,我只是说Foo ## _Encoding_DefaultBinary
,它会发生。