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