diff options
Diffstat (limited to 'third_party/rust/failure/src/result_ext.rs')
-rw-r--r-- | third_party/rust/failure/src/result_ext.rs | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/third_party/rust/failure/src/result_ext.rs b/third_party/rust/failure/src/result_ext.rs new file mode 100644 index 0000000000..f4125cdd68 --- /dev/null +++ b/third_party/rust/failure/src/result_ext.rs @@ -0,0 +1,203 @@ +use core::fmt::Display; + +use {Compat, Context, Fail}; + +/// Extension methods for `Result`. +pub trait ResultExt<T, E> { + /// 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<T, Compat<E>>; + + /// 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<D>(self, context: D) -> Result<T, Context<D>> + 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<F, D>(self, f: F) -> Result<T, Context<D>> + where + F: FnOnce(&E) -> D, + D: Display + Send + Sync + 'static; +} + +impl<T, E> ResultExt<T, E> for Result<T, E> +where + E: Fail, +{ + fn compat(self) -> Result<T, Compat<E>> { + self.map_err(|err| err.compat()) + } + + fn context<D>(self, context: D) -> Result<T, Context<D>> + where + D: Display + Send + Sync + 'static, + { + self.map_err(|failure| failure.context(context)) + } + + fn with_context<F, D>(self, f: F) -> Result<T, Context<D>> + 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<T> ResultExt<T, Error> for Result<T, Error> { + fn compat(self) -> Result<T, Compat<Error>> { + self.map_err(|err| err.compat()) + } + + fn context<D>(self, context: D) -> Result<T, Context<D>> where + D: Display + Send + Sync + 'static + { + self.map_err(|failure| failure.context(context)) + } + + fn with_context<F, D>(self, f: F) -> Result<T, Context<D>> where + F: FnOnce(&Error) -> D, + D: Display + Send + Sync + 'static + { + self.map_err(|failure| { + let context = f(&failure); + failure.context(context) + }) + } + } +} |