Add error generator macro
This commit is contained in:
parent
cb855ae335
commit
2f03077abf
2 changed files with 114 additions and 6 deletions
113
libimagerror/src/error_gen.rs
Normal file
113
libimagerror/src/error_gen.rs
Normal file
|
@ -0,0 +1,113 @@
|
|||
#[macro_export]
|
||||
macro_rules! generate_error_types {
|
||||
(
|
||||
$name: ident,
|
||||
$kindname: ident,
|
||||
$($kind:ident => $string:expr),*
|
||||
) => {
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum $kindname {
|
||||
$( $kind ),*
|
||||
}
|
||||
|
||||
impl Display for $kindname {
|
||||
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
|
||||
let s = match *self {
|
||||
$( $kindname::$kind => $string ),*
|
||||
};
|
||||
try!(write!(fmt, "{}", s));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct $name {
|
||||
err_type: $kindname,
|
||||
cause: Option<Box<Error>>,
|
||||
}
|
||||
|
||||
impl $name {
|
||||
|
||||
pub fn new(errtype: $kindname, cause: Option<Box<Error>>) -> $name {
|
||||
$name {
|
||||
err_type: errtype,
|
||||
cause: cause,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn err_type(&self) -> $kindname {
|
||||
self.err_type
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Display for $name {
|
||||
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
|
||||
try!(write!(fmt, "[{}]", self.err_type));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Error for $name {
|
||||
|
||||
fn description(&self) -> &str {
|
||||
match self.err_type {
|
||||
$( $kindname::$kind => $string ),*
|
||||
}
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&Error> {
|
||||
self.cause.as_ref().map(|e| &**e)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::error::Error;
|
||||
use std::fmt::Error as FmtError;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
generate_error_types!(TestError, TestErrorKind,
|
||||
TestErrorKindA => "testerrorkind a",
|
||||
TestErrorKindB => "testerrorkind B");
|
||||
|
||||
#[test]
|
||||
fn test_a() {
|
||||
let kind = TestErrorKind::TestErrorKindA;
|
||||
assert_eq!(String::from("testerrorkind a"), format!("{}", kind));
|
||||
|
||||
let e = TestError::new(kind, None);
|
||||
assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_b() {
|
||||
let kind = TestErrorKind::TestErrorKindB;
|
||||
assert_eq!(String::from("testerrorkind B"), format!("{}", kind));
|
||||
|
||||
let e = TestError::new(kind, None);
|
||||
assert_eq!(String::from("[testerrorkind B]"), format!("{}", e));
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ab() {
|
||||
let kinda = TestErrorKind::TestErrorKindA;
|
||||
let kindb = TestErrorKind::TestErrorKindB;
|
||||
assert_eq!(String::from("testerrorkind a"), format!("{}", kinda));
|
||||
assert_eq!(String::from("testerrorkind B"), format!("{}", kindb));
|
||||
|
||||
let e = TestError::new(kinda, Some(Box::new(TestError::new(kindb, None))));
|
||||
assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
|
||||
assert_eq!(TestErrorKind::TestErrorKindA, e.err_type());
|
||||
assert_eq!(String::from("[testerrorkind B]"), format!("{}", e.cause().unwrap()));
|
||||
}
|
||||
}
|
|
@ -1,6 +1 @@
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn it_works() {
|
||||
}
|
||||
}
|
||||
pub mod error_gen;
|
||||
|
|
Loading…
Reference in a new issue