3个版本
0.1.2 | 2023年3月25日 |
---|---|
0.1.1 | 2022年9月24日 |
0.1.0 | 2022年8月29日 |
在Rust模式中排名第1164
每月下载量22次
18KB
84 行
hb_error
此crate包含用于创建错误类型和处理错误的宏和特质。
此crate的主要功能是hberror宏和上下文宏。
hberror宏
此宏用于生成错误类型的所有样板代码,以便它们具有相同的格式。
概述
此宏应用于如下结构的struct。
#[hberror]
struct ExampleError {
}
此宏将修改struct以添加msg和inner_msgs字段,以及为new、ErrorContext、Display和Debug执行impl。这将生成以下代码
pub struct ExampleError {
msg: String,
inner_msgs: Vec<String>,
}
impl ExampleError {
pub fn new() -> ExampleError {
ExampleError {
msg: default::Default(),
inner_msgs: default::Default(),
}
}
}
impl ErrorContext for ExampleError {
fn make_inner(mut self) -> ExampleError {
self.inner_msgs.push(self.msg);
self.msg = String::new();
self
}
fn msg<T: Into<String>>(mut self, msg: T) -> ExampleError {
self.msg = msg.into();
self
}
}
impl std::fmt::Display for ExampleError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
write!(f,"{}{}", self.msg, self.inner_msgs.join("\n...because..."))
}
}
impl std::fmt::Debug for ExampleError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
write!(f,"{}{}", self.msg, self.inner_msgs.join("\n...because..."))
}
}
自定义字段和消息
此宏还具有处理自定义字段和自定义消息的能力。使用这些自定义字段上的Default属性将告诉宏使用new函数中提供的值而不是default::Default()。
#[hberror("{self.custom_field}:{self.msg}{self.inner_msgs.join(\"\n...due to...\")}")]
struct ExampleError {
#[Default(10)]
custom_field: i32,
}
这变成
pub struct ExampleError {
msg: String,
inner_msgs: Vec<String>,
custom_field: i32
}
impl ExampleError {
pub fn new() -> ExampleError {
ExampleError {
msg: default::Default(),
inner_msgs: default::Default(),
custom_field: 10
}
}
}
impl ErrorContext for ExampleError {
fn make_inner(mut self) -> ExampleError {
self.inner_msgs.push(self.msg);
self.msg = String::new();
self
}
fn msg<T: Into<String>>(mut self, msg: T) -> ExampleError {
self.msg = msg.into();
self
}
}
impl std::fmt::Display for ExampleError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
write!(f,"{}:{}{}", self.custom_field, self.msg, self.inner_msgs.join("\n...due to..."))
}
}
impl std::fmt::Debug for ExampleError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
write!(f,"{}:{}{}", self.custom_field, self.msg, self.inner_msgs.join("\n...due to..."))
}
}
从其他错误轻松转换
您还可以定义要转换的错误并将它们存储为source变量,这些变量将在消息后打印出来。Source属性告诉宏哪些字段作为源进行处理。将使用具有Source结尾的结构身份创建一个枚举(例如ExampleErrorSource)。此枚举将为具有源属性的字段以及一个None值创建变体。源变体使用字段身份作为枚举变体身份创建,并包含提供的错误类型。
这意味着可以在不进行任何额外工作的前提下在错误类型上使用context或convert_error宏。
#[hberror]
struct ExampleError {
#[Source]
IOError: std::io::Error,
}
这变成
use std::default;
pub struct ExampleError {
msg: String,
inner_msgs: Vec<String>,
source: ExampleErrorSource,
}
impl ExampleError {
pub fn new() -> ExampleError {
ExampleError {
msg: default::Default(),
inner_msgs: default::Default(),
source: default::Default(),
}
}
pub fn source(mut self, s: ExampleErrorSource) -> ExampleError {
self.source = s;
self
}
}
impl ErrorContext for ExampleError {
fn make_inner(mut self) -> ExampleError {
self.inner_msgs.push(self.msg);
self.msg = String::new();
self
}
fn msg<T: Into<String>>(mut self, msg: T) -> ExampleError {
self.msg = msg.into();
self
}
}
impl std::fmt::Display for ExampleError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
write!(f,"{}{}{}", self.msg, self.inner_msgs.join("\n...due to..."), self.source)
}
}
impl std::fmt::Debug for ExampleError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
write!(f,"{}{}{}", self.msg, self.inner_msgs.join("\n...due to..."), self.source)
}
}
pub enum ExampleErrorSource {
None,
IOError(std::io::Error),
}
impl std::default::Default for ExampleErrorSource {
fn default() -> Self { ExampleErrorSource::None }
}
impl std::fmt::Display for ExampleErrorSource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
match self {
ExampleErrorSource::None => Ok(()),
ExampleErrorSource::IOError(e) => write!("\n...Source Error...{}", e)
}
}
}
impl std::fmt::Debug for ExampleErrorSource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
match self {
ExampleErrorSource::None => Ok(()),
ExampleErrorSource::IOError(e) => write!("\n...Source Error...{}", e)
}
}
}
convert宏
将函数返回的错误转换为函数正确的类型,并添加提供的上下文消息。这需要从源错误实现From到返回类型错误。此宏将以下函数...
#[context("context message")]
fn basic_exampleerror() -> Result<(), ExampleError> {
if io_error()? {
return example_error().map_err(|e| e.msg("msgs are great"));
}
example_error()
}
转换为...
fn basic_exampleerror() -> Result<(), ExampleError> {
#[allow(unreachable_code)]
let ret: Result<(), ExampleError> = {
#[warn(unreachable_code)]
if hb_error::ConvertInto::Result<(), ExampleError>::convert(io_error()).map_err(|er| er.make_inner().msg("context message")? {
return hb_error::ConvertInto::Result<(), ExampleError>::convert(example_error().map_err(|e| e.msg("msgs are great"))).map_err(|er| er.make_inner().msg("context message");
}
example_error()
};
#[allow(unreachable_code)]
ret.map_err(|er| e.make_inner().msg("context message")
}
依赖关系
~1.5MB
~35K SLoC