#err #error #enums #inline #usize #go #variant

err-as-you-go

轻松的嵌入式错误类型

4个版本

0.1.3 2023年3月18日
0.1.2 2023年3月18日
0.1.1 2023年3月18日
0.1.0 2023年3月18日

#1456进程宏

Download history 22/week @ 2024-03-30 5/week @ 2024-04-06

每月51次下载

Apache-2.0 OR MIT

36KB
856

crates-io docs-rs github

err-as-you-go

在行内生成 enum 错误类型。

如果你想要

  • 在行内轻松抛出错误,就像使用 anyhow
  • 使你的错误类型可以像 thiserror 一样优雅地处理

那么这个crate就是为你准备的!

use err_as_you_go::err_as_you_go;

#[err_as_you_go]
fn shave_yaks(
    num_yaks: usize,
    empty_buckets: usize,
    num_razors: usize,
) -> Result<(), ShaveYaksError> {
    if num_razors == 0 {
        return Err(err!(NotEnoughRazors));
    }
    if num_yaks > empty_buckets {
        return Err(err!(NotEnoughBuckets {
            got: usize = empty_buckets,
            required: usize = num_yaks,
        }));
    }
    Ok(())
}

底层,会生成类似这样的结构体

enum ShaveYaksError { // name and visibility are taken from function return type and visibility
    NotEnoughRazors,
    NotEnoughBuckets {
        got: usize,
        required: usize,
    }
}

重要的是,你可以在生成的结构体上派生,并且传递属性,这允许你使用像 thiserror 这样的crate。


#[err_as_you_go(derive(Debug, thiserror::Error))]
fn shave_yaks(
    num_yaks: usize,
    empty_buckets: usize,
    num_razors: usize,
) -> Result<(), ShaveYaksError> {
    if num_razors == 0 {
        return Err(err!(
            #[error("not enough razors!")]
            NotEnoughRazors
        ));
    }
    if num_yaks > empty_buckets {
        return Err(err!(
            #[error("not enough buckets - needed {required}")]
            NotEnoughBuckets {
                got: usize = empty_buckets,
                required: usize = num_yaks,
            }
        ));
    }
    Ok(())
}

这会生成以下内容

#[derive(Debug, thiserror::Error)]
enum ShaveYaksError {
    #[error("not enough razors!")]
    NotEnoughRazors,
    #[error("not enough buckets - needed {required}")]
    NotEnoughBuckets {
        got: usize,
        required: usize,
    }
}

并且 err! 宏调用会被替换为结构体实例化 - 不论它们在函数体中的位置如何!

如果你需要在函数内部重用相同的变体,只需使用正常的构造语法

#[err_as_you_go]
fn foo() -> Result<(), FooError> {
    fallible_op().map_err(|e| err!(IoError(io::Error = e)));
    Err(FooError::IoError(todo!()))
}

依赖

~3–12MB
~122K SLoC