use core::fmt::Display; use {Compat, Context, Fail}; /// Extension methods for `Result`. pub trait ResultExt { /// Wraps the error in `Compat` to make it compatible with older error /// handling APIs that expect `std::error::Error`. /// /// # Examples /// /// ``` /// # fn main() { /// # tests::run_test(); /// # } /// # /// # #[cfg(not(all(feature = "std", feature = "derive")))] mod tests { pub fn run_test() { } } /// # /// # #[cfg(all(feature = "std", feature = "derive"))] mod tests { /// use std::error::Error; /// # use std::fmt; /// # /// # extern crate failure; /// # /// # use tests::failure::ResultExt; /// # /// # #[derive(Debug)] /// struct CustomError; /// /// impl Error for CustomError { /// fn description(&self) -> &str { /// "My custom error message" /// } /// /// fn cause(&self) -> Option<&Error> { /// None /// } /// } /// # /// # impl fmt::Display for CustomError { /// # fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { /// # write!(f, "{}", self.description()) /// # } /// # } /// # /// # pub fn run_test() { /// /// let x = (|| -> Result<(), failure::Error> { /// Err(CustomError).compat()? /// })().with_context(|e| { /// format!("An error occured: {}", e) /// }).unwrap_err(); /// /// let x = format!("{}", x); /// /// assert_eq!(x, "An error occured: My custom error message"); /// # } /// /// # } /// ``` fn compat(self) -> Result>; /// Wraps the error type in a context type. /// /// # Examples /// /// ``` /// # #[cfg(all(feature = "std", feature = "derive"))] /// # #[macro_use] extern crate failure; /// # /// # #[cfg(all(feature = "std", feature = "derive"))] /// # #[macro_use] extern crate failure_derive; /// # /// # fn main() { /// # tests::run_test(); /// # } /// # /// # #[cfg(not(all(feature = "std", feature = "derive")))] mod tests { pub fn run_test() { } } /// # /// # #[cfg(all(feature = "std", feature = "derive"))] mod tests { /// # /// # use failure::{self, ResultExt}; /// # /// #[derive(Fail, Debug)] /// #[fail(display = "")] /// struct CustomError; /// # /// # pub fn run_test() { /// /// let x = (|| -> Result<(), failure::Error> { /// Err(CustomError)? /// })().context(format!("An error occured")).unwrap_err(); /// /// let x = format!("{}", x); /// /// assert_eq!(x, "An error occured"); /// # } /// /// # } /// ``` fn context(self, context: D) -> Result> where D: Display + Send + Sync + 'static; /// Wraps the error type in a context type generated by looking at the /// error value. /// /// # Examples /// /// ``` /// # #[cfg(all(feature = "std", feature = "derive"))] /// # #[macro_use] extern crate failure; /// # /// # #[cfg(all(feature = "std", feature = "derive"))] /// # #[macro_use] extern crate failure_derive; /// # /// # fn main() { /// # tests::run_test(); /// # } /// # /// # #[cfg(not(all(feature = "std", feature = "derive")))] mod tests { pub fn run_test() { } } /// # /// # #[cfg(all(feature = "std", feature = "derive"))] mod tests { /// # /// # use failure::{self, ResultExt}; /// # /// #[derive(Fail, Debug)] /// #[fail(display = "My custom error message")] /// struct CustomError; /// # /// # pub fn run_test() { /// /// let x = (|| -> Result<(), failure::Error> { /// Err(CustomError)? /// })().with_context(|e| { /// format!("An error occured: {}", e) /// }).unwrap_err(); /// /// let x = format!("{}", x); /// /// assert_eq!(x, "An error occured: My custom error message"); /// # } /// /// # } /// ``` fn with_context(self, f: F) -> Result> where F: FnOnce(&E) -> D, D: Display + Send + Sync + 'static; } impl ResultExt for Result where E: Fail, { fn compat(self) -> Result> { self.map_err(|err| err.compat()) } fn context(self, context: D) -> Result> where D: Display + Send + Sync + 'static, { self.map_err(|failure| failure.context(context)) } fn with_context(self, f: F) -> Result> where F: FnOnce(&E) -> D, D: Display + Send + Sync + 'static, { self.map_err(|failure| { let context = f(&failure); failure.context(context) }) } } with_std! { use Error; impl ResultExt for Result { fn compat(self) -> Result> { self.map_err(|err| err.compat()) } fn context(self, context: D) -> Result> where D: Display + Send + Sync + 'static { self.map_err(|failure| failure.context(context)) } fn with_context(self, f: F) -> Result> where F: FnOnce(&Error) -> D, D: Display + Send + Sync + 'static { self.map_err(|failure| { let context = f(&failure); failure.context(context) }) } } }