23个不稳定版本 (10个破坏性更新)
| 0.11.3 | 2024年7月30日 |
|---|---|
| 0.11.1 | 2024年3月16日 |
| 0.10.4 | 2023年11月24日 |
| 0.5.1 | 2023年7月21日 |
在 过程宏 中排名第 49
每月下载量 62,506
在 218 个 库中(直接使用14个)
77KB
1K SLoC
manyhow
anyhow过程宏版本
Proc macro anyhow,结合了anyhow和proc-macro-error的思路,旨在改善过程宏开发,尤其关注错误处理。
动机
过程宏中的错误处理并不理想,因为过程宏的顶级函数在成功和失败的情况下都只能返回TokenStreams。这意味着我经常编写如下代码,将实际实现移动到单独的函数中,以便能够使用如?之类的 Rust 错误处理。
use proc_macro2::TokenStream as TokenStream2;
#[proc_macro]
pub fn my_macro(input: TokenStream) -> TokenStream {
match actual_implementation(input.into()) {
Ok(output) => output,
Err(error) => error.into_compile_error(),
}
.into()
}
fn actual_implementation(input: TokenStream2) -> syn::Result<TokenStream2> {
// ..
}
使用#[manyhow]宏
要激活错误处理,只需在任一过程宏实现上方添加#[manyhow],将上述示例简化为
use manyhow::manyhow;
use proc_macro2::TokenStream as TokenStream2;
#[manyhow]
#[proc_macro]
fn my_macro(input: TokenStream2) -> syn::Result<TokenStream2> {
// ..
}
请参阅不使用宏,以了解其底层展开内容。
被标记为#[manyhow]的过程宏函数可以接受和返回任何TokenStream,也可以返回Result<TokenStream, E>,其中E实现了ToTokensError。作为附加参数,可以指定一个占位符和/或发射器。
当用于 proc_macro 和 proc_macro_attribute 时,manyhow 属性可以接受一个可选标志。使用如下格式:#[manyhow(input_as_dummy)] 将会将类似 proc_macro 的函数的输入初始化为 虚拟的 &mut TokenStream,而 #[manyhow(item_as_dummy)] 在 proc_macro_attribute 上会使用注解的项目初始化虚拟对象。
无宏
manyhow 可以在不使用宏的情况下使用,可以通过添加 manyhow 和 default-features=false 来禁用。
使用方式基本相同,尽管需要直接调用 function、attribute 或 derive 之一,因此有一些额外的样板代码。
虽然示例使用闭包,也可以传递函数。上面的示例将变为
use proc_macro2::TokenStream as TokenStream2;
#[proc_macro]
pub fn my_macro(input: TokenStream) -> TokenStream {
manyhow::function(
input,
false,
|input: TokenStream2| -> syn::Result<TokenStream2> {
// ..
},
)
}
Emitter 和 虚拟的 TokenStream 也可以使用。函数和属性接受一个额外的布尔参数,用于控制输入/项目是否用作初始虚拟对象。
emitter: &mutEmitter
MacroHandler(定义 manyhow 可以与哪些闭包/函数一起使用的特质)可以接受对 Emitter 的可变引用。这允许收集错误,但不会立即失败。
Emitter::into_result 可以用来判断 Emitter 是否包含任何值。
use manyhow::{manyhow, Emitter, ErrorMessage};
use proc_macro2::TokenStream as TokenStream2;
#[manyhow]
#[proc_macro]
fn my_macro(input: TokenStream2, emitter: &mut Emitter) -> manyhow::Result<TokenStream2> {
// ..
emitter.emit(ErrorMessage::call_site("A fun error!"));
emitter.into_result()?;
// ..
}
dummy: &mutTokenStream
MacroHandler 还接受对 TokenStream 的可变引用,以便在宏出错的情况下发出一些虚拟代码。
这允许通过 ToTokens::to_tokens 添加标记等或直接设置虚拟代码,例如,*dummy = quote!{一些标记}。
依赖项
~96–580KB
~13K SLoC