9 个版本

0.1.1 2024 年 5 月 15 日
0.1.0 2024 年 5 月 10 日
0.0.6 2022 年 2 月 23 日
0.0.0 2022 年 1 月 21 日

#121 in Rust 模式

Download history 20220/week @ 2024-04-29 20860/week @ 2024-05-06 26352/week @ 2024-05-13 24820/week @ 2024-05-20 31958/week @ 2024-05-27 27438/week @ 2024-06-03 21693/week @ 2024-06-10 23436/week @ 2024-06-17 28381/week @ 2024-06-24 25785/week @ 2024-07-01 23899/week @ 2024-07-08 30447/week @ 2024-07-15 32472/week @ 2024-07-22 26454/week @ 2024-07-29 31113/week @ 2024-08-05 41563/week @ 2024-08-12

132,549 每月下载
用于 57 个 crate (13 直接)

MIT/Apache

14KB
196

crates.io CI commits-since rust 1.51.0+ badge

fatality

创建 致命性非致命性 错误的生成方法。

生成的源代码大量使用了 thiserror::Error 派生属性,并将任何未知注释传递给该属性。

动机

对于大型单一代码库,随着子系统的增加,使用 thiserror 定义的嵌套错误变体进行 match 变得非常繁琐。使用 anyhoweyre ——虽然它是一个应用——也带来了难以管理的痛苦,尤其是在中大型代码库中。

fatality 是解决这个问题的一种方法,通过使用注解扩展 thiserror::Error 来声明某些变体为 fatal,或将致命性提取转发到内部错误类型。

继续阅读!

用法

#[fatality] 默认提供了一个具有单个 fn is_fatal(&self) -> bool 方法的 trait Fatality

带有 forward 的注解需要 内部 错误类型也实现 trait Fatality

使用#[fatality(splitable)]进行注释,可以将类型拆分为两个子类型,一个Jfyi*和一个Fatal*,通过fn split(self) -> Result<Self::Jfyi, Self::Fatal>来实现。如果对splitable进行了注释。

derive宏实现了这些功能,并且可以根据thiserror注释进行调用延迟,具体是针对#[source]#[transparent]注释在枚举类型及其成员上的实现。

/// Fatality only works with `enum` for now.
/// It will automatically add `#[derive(Debug, thiserror::Error)]`
/// annotations.
#[fatality]
enum OhMy {
    #[error("An apple a day")]
    Itsgonnabefine,

    /// Forwards the `is_fatal` to the `InnerError`, which has to implement `trait Fatality` as well.
    #[fatal(forward)]
    #[error("Dropped dead")]
    ReallyReallyBad(#[source] InnerError),

    /// Also works on `#[error(transparent)]
    #[fatal(forward)]
    #[error(transparent)]
    Translucent(InnerError),


    /// Will always return `is_fatal` as `true`,
    /// irrespective of `#[error(transparent)]` or
    /// `#[source]` annotations.
    #[fatal]
    #[error("So dead")]
    SoDead(#[source] InnerError),
}
#[fatality(splitable)]
enum Yikes {
    #[error("An apple a day")]
    Orange,

    #[fatal]
    #[error("So dead")]
    Dead,
}

fn foo() -> Result<[u8;32], Yikes> {
    Err(Yikes::Dead)
}

fn i_call_foo() -> Result<(), FatalYikes> {
    // availble via a convenience trait `Nested` that is implemented
    // for any `Result` whose error type implements `Split`.
    let x: Result<[u8;32], Jfyi> = foo().into_nested()?;
}

fn i_call_foo_too() -> Result<(), FatalYikes> {
    if let Err(jfyi_and_fatal_ones) = foo() {
        // bail if bad, otherwise just log it
        log::warn!("Jfyi: {:?}", jfyi_and_fatal_ones.split()?);
    }
}

路线图

  • 可选地减少宏开销,用#[fatal($args)]#[error(..替换为#[fatal($args;..)],并为thiserror生成正确的#[error]注释。
  • finality添加一个可选参数:splitable确定这是一个需要处理的根错误,因此应将其拆分为两个枚举错误FatalJfyi,并使用trait Splitfn split() -> Result<Jfyi, Fatal> {..}
  • 允许对struct进行注释,使其成为全部致命或信息性的。

依赖关系

~1.8–2.8MB
~53K SLoC