Basically, I need the following function call to be evaluated at compile-time:
println!("{}", event_code(Event::B));
Function definition:
fn event_code(event: Event) -> EventCode {
match event {
Event::A => EventCode::One,
Event::B => EventCode::Two,
}
}
Here are the enums used above:
enum Event {
A,
B,
}
enum EventCode {
One,
Two,
}
I tried using const fn
, but after looking into the generated assembly code, I can see call
statements to the function in question, which I guess is because of calling the function in a non-constant context. My question is how can I write a simple macro that executes the fn event_code(event: Event) -> EventCode
at compile-time? I'm new to macro system, but I think procedural macros are my way to go. I've read the Rust Book Reference on Macros, and other blog posts, but I couldn't find an example similar to what I want to achieve, although it seems a simple task in my opinion. Am I going in the wrong direction by trying to achieve this using procedural macros? If not, I can see procedural macros mainly a 3-steps process - at least for function-like macros; parsing the input TokenStream
(e.g., by using syn
crate), do something with the parsed stream, and generate output code as TokenStream
(e.g,. by using quote
crate). I'm kind of puzzled with how can I convert the input TokenStream
, which should be a Event
variant, and if it's not return an error saying so, then use it as an argument for event_code
function, although being a stream of tokens, not an Event
enum type?
My goal is to achieve something similar to this:
let code = event_code!(Event::B);
// should expand to:
let code = EventCode::Two;
Edit 1: Fixed some typos
Edit 2: Fixed some typos
Edit 3: Mention helper crates
Edit 4: Fixed some typos