1 个不稳定版本
0.1.0 | 2021年6月15日 |
---|
#139 在 #spans
在 error_spanned 中使用
7KB
112 行
error_spanned
此crate旨在在进程宏库中使用。
此crate提供了一个名为 ErrorSpanned
的trait和一个名为 error_spanned_derive::ErrorSpanned
的derive宏。该trait强制要求错误类型支持转换为 syn::Error
和 proc_macro2::TokenStream
。
该trait由由 #[derive(ErrorSpanned)]
生成的包装结构实现。该结构存储行、文件和范围信息。
示例
对于名为 error_spanned.rs
的文件
use std::fmt::Display;
use error_spanned::{ErrorSpanned as _, ErrorSpanned};
use proc_macro2::Span;
// Deriving ErrorSpanned generates a struct named `CustomErrorSpanned`
// and a function-like macro named custom_error!().
#[derive(Debug, ErrorSpanned)]
enum CustomError {
Error1,
Error2(String),
Error3 {
x: i32,
y: i32,
},
}
impl Display for CustomError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
match self {
CustomError::Error1 => write!(f, "Error1"),
CustomError::Error2(string) => write!(f, "Error2({})", string),
CustomError::Error3 {x, y} => write!(f, "Error3 {{ x = {}, y = {} }}",x, y),
}
}
}
impl std::error::Error for CustomError {}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Printing the following errors will also print line and file
println!("{}", custom_error!(Error1, Span::call_site()));
println!("{}", custom_error!(Error2("Hello world".into()), Span::call_site()));
println!("{}", custom_error!(Error3{x: 1, y: 2}, Span::call_site()));
Ok(())
}
输出如下
Line: 31, File: /Users/mihir/rust_crates/error_spanned/tests/error_spanned.rs:
Error1
Line: 32, File: /Users/mihir/rust_crates/error_spanned/tests/error_spanned.rs:
Error2(Hello world)
Line: 33, File: /Users/mihir/rust_crates/error_spanned/tests/error_spanned.rs:
Error3 { x = 1, y = 2 }
如上例所示,错误应通过生成的宏(如 custom_error!()
)传播。生成的宏是错误枚举的蛇形版本。
生成的宏接受错误变体(不是完整路径)作为第一个参数,范围作为第二个参数。
该宏返回的类型是 <enum_named>Spanned
。该类型可以实现转换为 proc_macro2::TokenStream
或 syn::Error
,因为它实现了 ErrorSpanned
。在转换为 proc_macro2::TokenStream
或 syn::Error
时,它保留了范围信息。
依赖项
~1.5MB
~37K SLoC