I'm trying to write a fairly complex macro in Rust. Here is what the macro would look like on the outside:
supported_messages![
OpenSecureChannelRequest,
OpenSecureChannelResponse,
CloseSecureChannelRequest,
CloseSecureChannelResponse,
// This list will eventually have 100s of values
];
On the inside, it expands each id into something like this (plus a lot of other boiler plate):
ObjectId::Foo_Encoding_DefaultBinary => { SupportedMessage::Foo(Foo::decode()?) },
This pseudo-macro provides the gist of what I'm doing:
macro_rules! supported_messages {
[ $( $x:ident ), * ] => {
$( ObjectId::$x_Encoding_DefaultBinary => {
SupportedMessage::$x($x::decode()?)
}, )*
}
The full macro and source is online to see here.
The macro takes an array of ids, and for each id spews out a set of match patterns similar to the example above.
I can't take the identifier $x
, e.g. Foo
and turn it into a new identifier Foo_Encoding_DefaultBinary
.
Rust has a concat_idents!()
, but from what I've read it's practically useless and it's deprecated. Is there another way? Procedural macros aren't available on the stable compiler yet and may not be easy to use either.
At present, I'm generating most of the other boilerplate automatically but have to write the code above by hand. It's very tedious.
Is there a way to do this?
In C, I'd just say Foo ## _Encoding_DefaultBinary
and it would happen.