snippetrustMajor
How to write a custom derive macro?
Viewed 0 times
howwritemacroderivecustom
Problem
I'm trying to write my own derive mode macro in Rust, and the documentation on it is somewhat lacking in examples.
I have a struct like:
I want my macro to generate a method à la
What are the basic steps to use the
I have a struct like:
#[derive(MyMacroHere)]
struct Example {
id: i64,
value: Option,
}I want my macro to generate a method à la
fn set_fields(&mut self, id: i64, value: Option) {
// ...
}What are the basic steps to use the
TokenStream trait to achieve something like that?Solution
-
Create a crate for your procedural macros:
-
Edit the Cargo.toml to make it a procedural macro crate:
-
Implement your procedural macro:
-
Import the procedural macro and use it:
The hard part is in implementation of the macro. Most people use the syn and quote crates to parse the incoming Rust code and then generate new code.
For example, syn's documentation starts with an example of a custom derive. You will parse the struct (or enum or union) and then handle the various ways of defining a struct (unit, tuple, named fields). You'll collect the information you need (type, maybe name), then you'll generate the appropriate code.
See also:
Create a crate for your procedural macros:
cargo new my_derive --lib
-
Edit the Cargo.toml to make it a procedural macro crate:
[lib]
proc-macro = true
-
Implement your procedural macro:
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro_derive(MyMacroHere)]
pub fn my_macro_here_derive(input: TokenStream) -> TokenStream {
// ...
}
-
Import the procedural macro and use it:
extern crate my_derive;
use my_derive::MyMacroHere;
#[derive(MyMacroHere)]
struct Example {
id: i64,
value: Option,
}
The hard part is in implementation of the macro. Most people use the syn and quote crates to parse the incoming Rust code and then generate new code.
For example, syn's documentation starts with an example of a custom derive. You will parse the struct (or enum or union) and then handle the various ways of defining a struct (unit, tuple, named fields). You'll collect the information you need (type, maybe name), then you'll generate the appropriate code.
See also:
- How to Write a Custom
deriveMacro
- Documentation for
proc_macro
- Documentation for
syn
- Documentation for
quote
- Is it possible to add your own derivable traits, or are these fixed by the compiler?
Context
Stack Overflow Q#53135923, score: 63
Revisions (0)
No revisions yet.