diff --git a/libimagerror/src/error_gen.rs b/libimagerror/src/error_gen.rs new file mode 100644 index 00000000..471c6362 --- /dev/null +++ b/libimagerror/src/error_gen.rs @@ -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>, + } + + impl $name { + + pub fn new(errtype: $kindname, cause: Option>) -> $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())); + } +} diff --git a/libimagerror/src/lib.rs b/libimagerror/src/lib.rs index cdfbe1aa..9f79f549 100644 --- a/libimagerror/src/lib.rs +++ b/libimagerror/src/lib.rs @@ -1,6 +1 @@ -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - } -} +pub mod error_gen;