#error #thiserror #fatal #variant #forward #extension #fatality

fatality-proc-macro

Fatality 扩展 - crate 的 proc-macro 部分

7 个版本

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

#11 in #fatal

Download history 20770/week @ 2024-04-26 20600/week @ 2024-05-03 25368/week @ 2024-05-10 22584/week @ 2024-05-17 33746/week @ 2024-05-24 28335/week @ 2024-05-31 23021/week @ 2024-06-07 22744/week @ 2024-06-14 29249/week @ 2024-06-21 21919/week @ 2024-06-28 24269/week @ 2024-07-05 30345/week @ 2024-07-12 32805/week @ 2024-07-19 30245/week @ 2024-07-26 28031/week @ 2024-08-02 33167/week @ 2024-08-09

130,259 每月下载量
58 个 crate 中使用(通过 fatality

MIT/Apache

46KB
1K SLoC

crates.io CI commits-since rust 1.51.0+ badge

fatality

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

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

动机

对于大型单体仓库,随着子系统的增加,最终会变得非常繁琐,需要使用 match 与用 thiserror 定义的嵌套错误变体进行匹配。在使用 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 被注解。

派生宏实现了它们,并且可以根据 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>
  • 允许对 结构体 进行注释,可以是致命的或信息性的。

依赖项

~1.8–2.7MB
~53K SLoC