GitHunt
LI

liweinan/macro-example

macro-example

Rust 属性过程宏学习示例

这是一个用于学习 Rust 属性过程宏(proc_macro_attribute)的极简示例项目。项目演示了如何创建和使用自定义属性宏,结合 Tokio 异步编程进行实践。

项目结构

macro-example/
├── Cargo.toml              # 主项目配置
├── src/
│   └── main.rs             # 示例代码
└── tokio-simple-macro/     # proc-macro crate
    ├── Cargo.toml
    └── src/
        └── lib.rs          # 属性宏实现

功能特性

项目实现了三个自定义属性宏,用于演示不同的使用场景:

1. log_entry - 函数日志记录

为函数自动添加进入日志,并打印所有参数的值。

#[log_entry("进入示例函数")]
fn example_with_log(num: i32, text: String) {
    // 函数体
}

功能:

  • 自动打印函数名和自定义消息
  • 自动打印所有函数参数及其值

2. measure_time - 执行时间统计

自动测量函数的执行时间,支持同步和异步函数。

#[measure_time]
async fn example_with_timing() -> i32 {
    tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
    100
}

功能:

  • 自动检测函数是否为异步
  • 测量并打印函数执行耗时
  • 保持原函数的返回值和行为

3. show_streams - 调试工具

在编译时打印 TokenStream 和 AST 信息,用于调试和学习。

#[show_streams(verbose)]  // 传入 "verbose" 或 "v" 查看详细信息
fn debug_example(x: i32, y: String) -> bool {
    true
}

功能:

  • 打印属性参数(attr)
  • 打印完整的函数 TokenStream
  • 详细模式显示:函数名、是否异步、参数详情、类型信息、返回类型

使用方法

运行示例

# 编译并运行
cargo run

# 查看编译时的调试信息(show_streams 宏的输出)
cargo build

运行输出示例

=== 属性宏示例 ===

[LOG] 进入示例函数: example_with_log
  num: 42
  text: "hello"
这是使用 log_entry 宏的函数
处理参数: num=42, text=hello
[TIMING] example_with_timing 执行耗时: 501.29875ms
函数返回值: 100

[LOG] 组合示例函数: example_combined
  a: 100
  b: 200
[TIMING] example_combined 执行耗时: 301.905625ms
组合宏返回值: 300

编译时输出(show_streams 宏)

=== show_streams 宏调试信息 ===
属性参数 (attr): "verbose"
详细模式: true
函数名: debug_example
是否异步: false
参数数量: 2
--- 参数详情 ---
  参数 0: _x (类型: i32)
  参数 1: _y (类型: String)
返回类型: bool
完整项 (item): "fn debug_example(_x: i32, _y: String) -> bool { ... }"
==============================

学习要点

属性宏基础

  1. 宏函数签名

    #[proc_macro_attribute]
    pub fn my_attribute(attr: TokenStream, item: TokenStream) -> TokenStream
    • attr: 属性参数内容
    • item: 被装饰的完整项
    • 返回值:替换后的新代码
  2. TokenStream 处理

    • 使用 syn crate 解析 TokenStream 为 AST
    • 使用 quote! 宏生成新的 TokenStream
  3. AST 操作

    • ItemFn: 函数项
    • FnArg: 函数参数
    • Type: 类型信息

关键技术

  • 解析函数签名:提取函数名、参数、返回类型
  • 代码生成:使用 quote! 宏生成新代码
  • 异步函数检测:通过 fn_sig.asyncness 判断
  • 参数提取:遍历 fn_sig.inputs 获取参数信息

依赖说明

主项目依赖

  • tokio: 异步运行时
  • tokio-simple-macro: 本地 proc-macro crate

Proc-macro crate 依赖

  • syn: 解析 TokenStream 为 AST
  • quote: 生成新的 TokenStream
  • proc-macro2: proc-macro 的包装库

扩展建议

可以尝试实现以下功能来进一步学习:

  1. 错误处理宏:自动添加错误处理和日志
  2. 缓存宏:为函数添加结果缓存
  3. 重试宏:自动重试失败的异步操作
  4. 权限检查宏:在函数执行前进行权限验证

参考资料

许可证

本项目仅用于学习目的。