//! Error handling. pub use failure::{Error, Fail}; use std::fmt; macro_rules! ok { ($v:expr, $msg:expr) => { match $v { Some(v) => Ok(v), None => Err($crate::err::err_msg($msg)), } }; } macro_rules! flag_ok { ($t:ident$(::$tc:ident)*, $v:expr) => { { let v = $v; match $t$(::$tc)*::from_bits(v) { Some(v) => Ok(v), None => Err($crate::err::ReprError::new(stringify!($t), v)), } } }; } macro_rules! bail { ($e:expr) => { return Err($crate::err::err_msg($e)); }; } #[macro_export] macro_rules! backtrace { ($e:expr) => { if cfg!(debug_assertions) { dbg!($e.backtrace()); } } } /// Returns an `Error` with a static string. /// /// # Examples /// /// ``` /// use maraiah::err::err_msg; /// /// assert_eq!(format!("{}", err_msg("oh no not things")), /// "oh no not things"); /// ``` pub fn err_msg(msg: &'static str) -> Error {ErrMsg(msg).into()} impl ParseEnumError { /// Returns an `Error` with a message for enumeration parsing errata. /// /// # Examples /// /// ``` /// use maraiah::err::ParseEnumError; /// /// assert_eq!(format!("{}", ParseEnumError::new("TypeName")), /// "could not parse TypeName"); /// ``` #[inline] pub const fn new(t: &'static str) -> Self { Self(t) } } impl ParseFlagError { /// Returns an `Error` with a message for flag parsing errata. /// /// # Examples /// /// ``` /// use maraiah::err::ParseFlagError; /// /// assert_eq!(format!("{}", ParseFlagError::new("TypeName")), /// "could not parse TypeName"); /// ``` #[inline] pub const fn new(t: &'static str) -> Self { Self(t) } } impl ReprError { /// Returns an `Error` with a message for representation errata. /// /// # Examples /// /// ``` /// use maraiah::err::ReprError; /// /// assert_eq!(format!("{}", ReprError::new("TypeName", 77)), /// "bad TypeName (77)"); /// ``` pub fn new>(t: &'static str, n: T) -> Self { Self(t, n.into()) } } impl Fail for ErrMsg {} impl Fail for ParseEnumError {} impl Fail for ParseFlagError {} impl Fail for ReprError {} impl fmt::Display for ParseEnumError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "could not parse {}", self.0) } } impl fmt::Display for ParseFlagError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "could not parse {}", self.0) } } impl fmt::Display for ReprError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "bad {} ({})", self.0, self.1) } } impl fmt::Display for ErrMsg { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.0) } } #[derive(Clone, Debug)] struct ErrMsg(&'static str); /// A parser error for an enumeration. #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct ParseEnumError(&'static str); /// A parser error for a bit field. #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct ParseFlagError(&'static str); /// A representation error for an integer. #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct ReprError(&'static str, i64); /// A generic `failure` based `Result` type. pub type ResultS = Result; // EOF