Reputation: 33
I'm stuck trying to "rename" a identifier inside a declarative macro, I have the renaming function already, but can't find a way to "execute" it inside the macro. Is this possible with declarative macros?
Example:
fn to_pascal_case(s: &str) -> String { ... }
macro_rules! test_gl_enum {
($n: ident) => { struct to_pascal_case(stringify!($n)); }
}
test_gl_enum!(VERTEX_SHADER);
expands to:
struct to_pascal_case(());
desired result would be:
struct VertexShader;
Upvotes: 0
Views: 1262
Reputation: 10216
You can't execute arbitrary code in a declarative macro. You have a couple of options:
Proc macros are basically just functions that take a TokenStream
and return a TokenStream
(with some variations between function-like, attribute and derive macros). They can contain arbitrary code, so you could absolutely parse the identifier and apply some transformation to it.
If you're going to take this route, you will likely want to use syn
and quote
, and I'd also very strongly recommend going through the proc macro workshop, which is a series of exercises to teach you the basics.
As is often the case, someone else has also had this problem, and has written a crate for it: https://crates.io/crates/casey
With that, you can write:
use casey::*;
macro_rules! test_gl_enum {
($n:ident) => {
struct pascal!($n);
};
}
Here, pascal!()
is a proc macro that does the transformation, and since it's a macro (rather than a function) it is also evaluated at compile time, so the expansion won't look like struct pascal!(my_enum_name);
Upvotes: 3