3个版本

使用旧的Rust 2015

0.1.2 2017年11月11日
0.1.1 2017年11月11日
0.1.0 2017年11月11日

#derive-error中排名24

每月下载量39
2 crate中使用

MIT/Apache

13KB
146

另一个派生错误(Yade)

Yade是一组派生宏,旨在生成Rust中使用Error特质时的样板代码。此crate支持enumstruct、单元、元组和ErrorKind风格的错误类型。

Yade并不旨在解决Rust Error特质中的任何问题。如果您对用于错误处理的替代特质感兴趣,该特质试图解决Error的不足,请查看Failure项目。

用法

请确保将yade crate添加到您的Cargo.toml

[dependencies]
yade = "*"

派生宏

Yade提供了两个派生宏,分别是YadeErrorYadeKind

YadeError是主要宏,可用于为许多错误结构体自动派生ErrorDisplay特质。

例如

#[macro_use] extern crate yade;
use std::fs::File;
use std::error::Error as StdError;

#[derive(Debug, YadeError)]
pub enum Error {
    #[display(msg = "File could not be found: {}", _0)]
    FileNotFound(String, #[cause] std::io::Error),

    #[display(msg = "Bad request: {}", params)]
    BadRequest {
        params: String,
    },
}

fn causes_error() -> Result<(), Error> {
    File::open("a_missing_file.txt")
        .map_err(|e| Error::FileNotFound("a_missing_file.txt".into(), e))?;

    Ok(())
}

fn main() {
    match causes_error() {
      Err(err) => {
          eprintln!("An error occured: {}", err);

          let mut err: &StdError = &err;
          while let Some(cause) = err.cause() {
              eprintln!(" - Cause: {}", cause);
              err = cause;
          }
      },
      _ => println!("Great success"),
    }
}

YadeKind提供以辅助使用ErrorKind枚举构建错误类型。

#[macro_use] extern crate yade;
use std::fs::File;
use std::error::Error as StdError;

#[derive(Debug, YadeError)]
#[display(msg = "{}", kind)]
pub struct Error {
    pub kind: ErrorKind,

    #[cause]
    pub cause: Option<Box<StdError>>,
}

#[derive(Debug, YadeKind)]
pub enum ErrorKind {
    #[display(msg = "File could not be found: {}", _0)]
    FileNotFound(String),

    #[display(msg = "World fell apart, oops")]
    AnotherError,
}

fn causes_error() -> Result<(), Error> {
    File::open("a_missing_file.txt")
        .map_err(|e| Error { kind: ErrorKind::FileNotFound("a_missing_file.txt".into()), cause: Some(Box::new(e)) })?;

    Ok(())
}

fn main() {
    match causes_error() {
        Err(err) => {
            eprintln!("An error occured: {}", err);

            let mut err: &StdError = &err;
            while let Some(cause) = err.cause() {
                eprintln!(" - Cause: {}", cause);
                err = cause;
            }
        },

        _ => println!("Great success"),
    }
}

常见问题解答

为什么不直接使用'failure'?

我强烈建议您查看failure crate,由withoutboats提供,它试图解决现有Error特质中的许多问题。它目前仍在早期开发阶段,但我相信'failure'或类似的东西将成为Rust中错误处理的未来。

话虽如此,'failure'更适合用于尚未围绕Rust标准库Error特质标准化的新库和应用。

Yade旨在作为一个即插即用的替代品,以保持与旧代码的兼容性。

为什么不直接使用'error-chain'?

自从'error-chain'诞生以来,我在几个项目中都使用了它,虽然我认为它是构建应用程序的有用工具,但我并不认为它非常适合库。

我主要的问题是'chain-chain'使模式匹配变得复杂。我还发现,像'chain-error'这样的基于宏的DSL在处理语法错误时对错误处理来说很混乱。(有derive-error-chain项目,但我认为它也有一些自己的问题。)

类似库

  • failure - 一种新的错误管理故事。
  • error_def - Rust 语法扩展,用于生成错误处理模板代码。
  • derive-error - 使用宏 1.1 的 Error 派生宏。
  • error-chain - 另一个错误模板库。

许可证

Yade 使用以下任一许可证:

贡献

除非您明确表示,否则根据 Apache-2.0 许可证定义的,您有意提交给作品的所有贡献,将按照上述方式双重许可,没有额外的条款或条件。

请参阅CONTRIBUTING 文件以获取更多信息。

依赖项

~2MB
~42K SLoC