1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
pub use std::error::Error; use std::convert::From; #[derive(Debug)] pub struct MyError { pub file: &'static str, pub line: u32, pub statement: String, pub description: String, pub cause: Option<Box<std::error::Error>>, } #[allow(unused_must_use)] impl std::fmt::Display for MyError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { if let Some(ref x ) = self.cause { write!(f, "{}\n", &**x); } write!(f, "{}:{} `{}`", self.file, self.line, self.statement) } } impl std::error::Error for MyError { fn description(&self) -> &str { return &*self.description; } fn cause(&self) -> Option<&std::error::Error> { if let Some(ref x) = self.cause { Some(&**x) } else { None } } } impl <'a>From<&'a str> for MyError { fn from(x: &str) -> MyError { MyError { file: "", line: 0, statement: x.to_string(), description: x.to_string(), cause: None, } } } #[macro_export] macro_rules! tryx { ($e:expr) => (match $e { Ok(x) => x , Err(err) => { let l = line!(); let f = file!(); return Err(MyError { file: f, line: l, statement: stringify!($e).to_string(), description: format!("{}:{} `{}` {}", f, l, stringify!($e), err.description()), cause: Some(Box::new(err)), }) } }) } #[macro_export] macro_rules! myerr { ($caption:expr) => ( { let l = line!(); let f = file!(); MyError { file: f, line: l, statement: $caption, description: format!("{}:{} {}", f, l, $caption), cause: None, } }) }