簡體   English   中英

如何創建proc_macro_attribute?

[英]How do I create a proc_macro_attribute?

現在proc_macros 已穩定下來 ,如何創建這樣的東西?

從我所看到的,可以在fn whatsitsname(attrs: TokenStream, code: TokenStream) -> TokenStream上放置#[proc_macro_attribute]批注,但是我該如何注冊? 如何添加自定義屬性?

Rust編譯器具有相當完整的測試套件 在尋找新功能的示例時,我經常從這里開始:

$ rg -c proc_macro_attribute
src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs:2
src/test/ui-fulldeps/auxiliary/attr_proc_macro.rs:1
[... 35 other matches ...]

這是一個完整的示例:

$ tree
.
├── Cargo.toml
├── my_macro
│   ├── Cargo.toml
│   ├── src
│   │   └── lib.rs
└── src
    └── main.rs

貨物清單

我們添加了對宏定義板條箱的依賴。

[package]
name = "foo"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]

[dependencies]
my_macro = { path = "my_macro" }

src / main.rs

我們導入屬性宏並將其添加到函數中。

#[macro_use]
extern crate my_macro;

#[log_entry_and_exit(hello, "world")]
fn this_will_be_destroyed() -> i32 {
    42
}

fn main() {
    dummy()
}

my_macro / Cargo.toml

我們將crate_type指定為proc_macro

[package]
name = "my_macro"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]

[lib]
crate_type = ["proc-macro"]

my_macro / src / lib.rs

我們將#[proc_macro_attribute]添加到應為宏的每個函數中。

extern crate proc_macro;

use proc_macro::*;

#[proc_macro_attribute]
pub fn log_entry_and_exit(args: TokenStream, input: TokenStream) -> TokenStream {
    let x = format!(r#"
        fn dummy() {{
            println!("entering");
            println!("args tokens: {{}}", {args});
            println!("input tokens: {{}}", {input});
            println!("exiting");
        }}
    "#,
            args = args.into_iter().count(),
            input = input.into_iter().count(),
    );

    x.parse().expect("Generated invalid tokens")
}

貨物運行

entering
args tokens: 3
input tokens: 7
exiting

“困難”部分是將TokenStream成有用的東西,然后輸出同樣有用的東西。 包裝箱synquote是這兩項任務的當前黃金標准。 Rust編程語言宏一章以及API文檔中 介紹了如何處理TokenStream

還有#[proc_macro] ,它采用以下形式的函數:

#[proc_macro]
pub fn the_name_of_the_macro(input: TokenStream) -> TokenStream

可以作為the_name_of_the_macro!(...)調用。

如果我正確理解RFC 1566 ,則您:

  • 創建一個類型為proc_macro的板條箱,即其Cargo.toml應該包含

     [lib] proc-macro = true 
  • 在該板條箱中,創建帶有#[proc_macro_attribute]注釋的實現。 #[proc_macro]函數的宏的#[proc_macro_derive]針對自定義函數的#[proc_macro_derive]的派生工作相同,只是它們只有一個TokenStream參數。 這些在proc_macro板條箱中定義。

    第一個令牌流是屬性中的參數,第二個令牌流是帶注釋項的主體。

  • 然后,在要使用該宏的板條箱中,只需依賴proc_macro板條箱,並使用#[macro_use]屬性( #[macro_use] extern crate …)將其導入。

那應該足夠了。

本書的附錄應擴展為提及#[proc_macro_derive]以外的其他proc宏類型。 可能不是錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM