如何编写自定义派生宏?

How to write a custom derive macro?

我正在尝试用 Rust 编写我自己的派生模式宏,其中的 documentation 有点缺少示例。

我有一个像这样的结构:

#[derive(MyMacroHere)]
struct Example {
    id: i64,
    value: Option<String>,
}

我希望我的宏生成一个方法à la

fn set_fields(&mut self, id: i64, value: Option<String>) {
    // ...
}

使用 TokenStream 特性实现类似目标的基本步骤是什么?

  1. 为您的程序宏创建一个箱子:

     cargo new my_derive --lib
    
  2. 编辑 Cargo.toml 使其成为程序宏箱:

     [lib]
     proc-macro = true
    
  3. 执行程序宏:

     extern crate proc_macro;
    
     use proc_macro::TokenStream;
    
     #[proc_macro_derive(MyMacroHere)]
     pub fn my_macro_here_derive(input: TokenStream) -> TokenStream { 
         // ...
     }
    
  4. 导入程序宏并使用它:

     extern crate my_derive;
    
     use my_derive::MyMacroHere;
    
     #[derive(MyMacroHere)]
     struct Example {
         id: i64,
         value: Option<String>,
     }
    

困难的部分在于宏的实现。大多数人使用 syn and quote crate 来解析传入的 Rust 代码,然后生成新代码。

例如,syn 的文档以 an example of a custom derive 开头。您将解析结构(或枚举或联合),然后处理定义结构(单元、元组、命名字段)的各种方式。您将收集所需的信息(类型,也许是名称),然后生成适当的代码。

另请参阅: