8 个版本

0.0.8 2022 年 12 月 13 日
0.0.7 2022 年 11 月 2 日
0.0.6 2022 年 9 月 1 日
0.0.5 2021 年 9 月 30 日

Rust 模式 中排名第 216

Download history 1058/week @ 2024-04-22 1039/week @ 2024-04-29 855/week @ 2024-05-06 804/week @ 2024-05-13 1024/week @ 2024-05-20 1191/week @ 2024-05-27 1297/week @ 2024-06-03 1127/week @ 2024-06-10 915/week @ 2024-06-17 1001/week @ 2024-06-24 528/week @ 2024-07-01 963/week @ 2024-07-08 1691/week @ 2024-07-15 563/week @ 2024-07-22 997/week @ 2024-07-29 1102/week @ 2024-08-05

每月下载量 4,399
46 个 crate 中使用 (直接使用 7 个)

Apache-2.0

75KB
1.5K SLoC

one_err

OneErr 一统天下。

有些出色的错误辅助 crate,我最喜欢的有 thiserroranyhow

但有时候你需要一些不同的东西。随着时间的推移,thiserror crate 可能会导致巨大的嵌套错误枚举树,而 anyhow 很难匹配。

有时候你需要与 std::io::Error 交互,但这种类型难以构造,不是 Clone,并且无法序列化。

OneErr 是在 std::io::Error 上的新类型,但使其可克隆、可序列化,并希望更易于使用。

std::io::ErrorKind 匹配

use one_err::*;

for res in [
    Ok("not-error"),
    Err(OneErr::from(std::io::ErrorKind::InvalidInput)),
    Err(OneErr::from(std::io::ErrorKind::ConnectionRefused)),
] {
    match res.map_err(|e| e.kind()) {
        Ok(ok) => assert_eq!("not-error", ok),
        Err(std::io::ErrorKind::InvalidInput) => (),
        Err(std::io::ErrorKind::ConnectionRefused) => (),
        oth => panic!("unexpected: {:?}", oth),
    }
}

ErrNo 匹配

use one_err::*;

for res in [
    Ok("not-error"),
    Err(OneErr::from(ErrNo::NoData)),
    Err(OneErr::from(ErrNo::Proto)),
] {
    match res.map_err(|e| e.errno()) {
        Ok(ok) => assert_eq!("not-error", ok),
        Err(ErrNo::NoData) => (),
        Err(ErrNo::Proto) => (),
        oth => panic!("unexpected: {:?}", oth),
    }
}

自定义匹配

use one_err::*;

const ERR_FOO: &str = "FOO";
const ERR_BAR: &str = "BAR";

for res in [
    Ok("not-error"),
    Err(OneErr::with_message(ERR_FOO, "foo test")),
    Err(OneErr::with_message(ERR_BAR, "bar test")),
] {
    match res.as_ref().map_err(|e| (e.str_kind(), e)) {
        Ok(ok) => assert_eq!("not-error", *ok),
        Err((ERR_FOO, e)) => assert_eq!("foo test", e.get_message().unwrap()),
        Err((ERR_BAR, e)) => assert_eq!("bar test", e.get_message().unwrap()),
        oth => panic!("unexpected: {:?}", oth),
    }
}

std::io 互操作性

use one_err::*;
use std::io::Read;

const CUSTOM_ERR: &str = "CustomError";

/// My custom Read that always errors.
pub struct ErrReader;

impl Read for ErrReader {
    fn read(&mut self, _buf: &mut [u8]) -> std::io::Result<usize> {
        Err(OneErr::new(CUSTOM_ERR).into())
    }
}

assert_eq!(
    r#"{"error":"CustomError"}"#,
    &ErrReader.read(&mut []).unwrap_err().to_string(),
);

序列化和解析

use one_err::*;

const CUSTOM_ERR: &str = "CustomError";

let err = OneErr::new(CUSTOM_ERR);
let enc = err.to_string();

assert_eq!(
    r#"{"error":"CustomError"}"#,
    &enc,
);

let dec: OneErr = enc.parse().unwrap();
assert_eq!(err, dec);

许可:Apache-2.0

依赖项

~0.5–1.2MB
~25K SLoC