我正在尝试在我正在使用的库中调试复杂的过程宏。
由于我不能使用带有宏的调试器,并且各种宏扩展工具在这里被证明是无用的,我正在寻找一种替代方法。
可以像函数一样运行程序宏并进行适当的调试吗?我想象将结果存储proc_macro::TokenStream
在一个变量中。
我正在尝试在我正在使用的库中调试复杂的过程宏。
由于我不能使用带有宏的调试器,并且各种宏扩展工具在这里被证明是无用的,我正在寻找一种替代方法。
可以像函数一样运行程序宏并进行适当的调试吗?我想象将结果存储proc_macro::TokenStream
在一个变量中。
proc-macro2
crate是一个替代品,除了它在proc_macro
宏之外可用 - 这使得它可测试。它的类型都可以与类型相互转换,proc_macro
并且具有相同的方法。
编写非平凡宏的通常模式是proc_macro
仅用于入口点,并proc-macro2
用于所有实际工作:
extern crate proc_macro;
use proc_macro2::TokenStream;
#[proc_macro]
pub fn my_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let output = transform_stream(TokenStream::from(input));
proc_macro::TokenStream::from(output)
}
// A testable function!
fn transform_stream(input: TokenStream) -> TokenStream {
// actual work goes here
}
导入项目很常见,proc-macro2
因此它们可以不限定使用,并且只使用完全限定名称proc_macro
,因为您将使用它的唯一时间是在入口点。通常将核心组件放在一个单独的库 crate 中,它不依赖于proc_macro
.
TokenStream
在测试中,您可以从字符串创建一个:
use std::str::FromStr;
let ts = TokenStream::from_str("fn foo() {}").unwrap();