19 个版本
使用旧的 Rust 2015
0.3.16 | 2017 年 10 月 4 日 |
---|---|
0.3.14 | 2017 年 6 月 11 日 |
0.3.12 | 2017 年 2 月 21 日 |
0.3.11 | 2016 年 8 月 27 日 |
0.3.2 | 2015 年 6 月 20 日 |
#1089 in Rust 模式
26KB
462 行
error_def:Rust 语法扩展,用于生成错误处理样板代码。
快速示例:以下代码
error_def! ExampleError {
AVariant
=> "Unit-like variant",
AVariantWithALongDescription
=> "Unit-like variant" ("A more verbose description"),
AVariantWithArgs { flim: u32, flam: u32 }
=> "Variant with args" ("This is a format string. flim is {}. flam is {}.", flim, flam),
AVariantWithACause { blah: bool, #[from] cause: io::Error }
=> "Variant with a cause" ("self.cause() would return Some({})", cause)
AVariantWithJustACause { #[from] blah: io::Error }
=> "This variant can be made `From` an `io::Error`"
}
大致展开为
pub enum ExampleError {
/// Unit-like variant
AVariant,
/// Unit-like variant
AVariantWithALongDescription,
/// Variant with args
AVariantWithArgs {
flim: u32,
flam: u32,
},
/// Variant with a cause
AVariantWithACause {
blah: bool,
cause: io::Error,
},
/// This variant can be made `From` an `io::Error`
AVariantWithJustACause {
blah: io::Error,
},
}
impl fmt::Debug for ExampleError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result<(), fmt::Error> {
match self {
&ExampleError::AVariant
=> write!(f, "AVariant /* {} */", self),
&ExampleError::AVariantWithALongDescription
=> write!(f, "AVariantWithALongDescription /* {} */", self),
&ExampleError::AVariantWithArgs { ref flim, ref flam }
=> write!(f, "AVariantWithArgs {{ flim: {:?}, flam: {:?} }} /* {} */", flim, flim, self),
&ExampleError::AVariantWithACause { ref blah, ref cause }
=> write!(f, "AVariantWithACause {{ blah: {:?}, cause: {:?} }} /* {} */", blah, cause, self),
&ExampleError::AVariantWithJustACause { ref blah }
=> write!(f, "AVariantWithJustACause {{ blah: {:?} }} /* {} */", blah, self),
}
}
}
impl fmt::Display for ExampleError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result<(), fmt::Error> {
match self {
&ExampleError::AVariant => {
try!(write!(f, "Unit-like variant."));
Ok(())
},
&ExampleError::AVariantWithALongDescription => {
try!(write!(f, "Unit-like variant"));
try!(write!(f, "A more verbose description"));
Ok(())
},
&ExampleError::AVariantWithArgs { ref flim, ref flam } => {
try!(write!(f, "Variant with args"));
try!(write!(f, "This is a format string. flim is {}. flam is {}.", flim, flam));
Ok(())
},
&ExampleError::AVariantWithACause { ref cause, .. } => {
try!(write!(f, "Variant with a cause"));
try!(write!(f, "self.cause() would return Some({})", cause));
Ok(())
},
&ExampleError::AVariantWithJustACause { .. } => {
try!(write!(f, "This variant can be made `From` an `io::Error`"));
Ok(())
},
}
}
}
impl Error for ExampleError {
fn description(&self) -> &str {
match self {
&ExampleError::AVariant => "Unit-like variant",
&ExampleError::AVariantWithALongDescription { .. } => "Unit-like variant",
&ExampleError::AVariantWithArgs { .. } => "Variant with args",
&ExampleError::AVariantWithACause { .. } => "Variant with a cause",
&ExampleError::AVariantWithJustACause { .. } => "This variant can be made `From` an `io::Error`",
}
}
fn cause(&self) -> Option<&Error> {
match self {
&ExampleError::AVariant => None,
&ExampleError::AVariantWithALongDescription { .. } => None,
&ExampleError::AVariantWithArgs { .. } => None,
&ExampleError::AVariantWithACause { ref cause, .. } => Some(cause as &Error),
&ExampleError::AVariantWithJustACause { ref blah, .. } => Some(blah as &Error),
}
}
}
impl From<io::Error> for ExampleError {
fn from(e: io::Error) -> ExampleError {
ExampleError::AVariantWithJustACause { blah: e }
}
}
说明: error_def
定义了一个 enum
,其中每个变体都与变体的描述配对。
error_def! SomeError {
AVariant => "A description",
AnotherVariant => "Another description",
}
此描述作为文档注释添加到变体,并通过调用 Error::description
返回。
assert!(SomeError::AVariant.description() == "A description")
变体可以是结构体-like。
error_def! SomeError {
AVariant { an_i32: i32 } => "I'm a variant",
}
变体还可以有一个可选的详细描述,它由一个格式字符串和一系列参数组成。详细描述放在简短描述之后,用括号括起来。如果变体是结构体,格式字符串的参数可以引用它的成员。
error_def! SomeError {
Io { cause: io::Error }
=> "I/O error occured!" ("Error: {}", cause),
}
error_def!
使用简短和详细描述提供 fmt::Display
和 fmt::Debug
的实现。在上面的例子中,SomeError::Io
将格式化为
I/O error occurred. Error: <
在此处插入 fmt::Display(cause) here
>
对于 fmt::Display
和
SomeError::Io { cause: <
在此处插入 fmt::Debug(cause) here
> } /* I/O error occurred. Error: <
在此处插入 fmt::Display(cause) here
> */
对于 fmt::Debug
。
结构体变体的成员可以标记为可选的伪属性 #[from]
。
error_def! SomeError {
Io {
foo: u32,
#[from] cause: io::Error,
} => "Io error"
}
这会导致在调用 Error::cause
时返回该成员。在上面的例子中,对 SomeError::Io
调用 Error::cause
将返回一个 Option<&Error>
,其中 &Error
指向一个 io::Error
。
如果一个结构体变体只有一个成员并且被标记为 #[from]
,那么将实现 From
以将该成员的类型转换为错误类型。
例如,如果我们定义一个错误如下
error_def! SomeError {
Io { #[from] cause: io::Error } => "I/O error",
}
那么 error_def!
将定义一个 impl
impl std::convert::From<io::Error> for SomeError {
fn from(e: io::Error) -> SomeError {
SomeError::Io {
cause: e,
}
}
}