use Fail; use std::error::Error; use std::fmt::{self, Debug, Display}; use std::sync::Mutex; /// Wrapper for `std` errors to make them `Sync`. /// /// This exists to coerce existing types that are only `Error + Send + /// 'static` into a `Fail`-compatible representation, most notably for /// types generated by `error-chain`. /// /// Unfortunately, this requires wrapping the error in a `Mutex`, which must /// be locked for every `Debug`/`Display`. Therefore, this should be /// something of a last resort in making the error work with `failure`. /// pub struct SyncFailure { inner: Mutex, } impl SyncFailure { /// Wraps a non-`Sync` `Error` in order to make it implement `Fail`. /// /// # Example /// /// ```rust /// extern crate failure; /// /// # use std::error::Error as StdError; /// # use std::fmt::{self, Display}; /// use failure::{Error, SyncFailure}; /// use std::cell::RefCell; /// /// #[derive(Debug)] /// struct NonSyncError { /// // RefCells are non-Sync, so structs containing them will be /// // non-Sync as well. /// count: RefCell, /// } /// /// // implement Display/Error for NonSyncError... /// # /// # impl StdError for NonSyncError { /// # fn description(&self) -> &str { /// # "oops!" /// # } /// # } /// # /// # impl Display for NonSyncError { /// # fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { /// # write!(f, "oops!") /// # } /// # } /// /// fn returns_error() -> Result<(), NonSyncError> { /// // Do stuff /// # Ok(()) /// } /// /// fn my_function() -> Result<(), Error> { /// // without the map_err here, we end up with a compile error /// // complaining that NonSyncError doesn't implement Sync. /// returns_error().map_err(SyncFailure::new)?; /// // Do more stuff /// # Ok(()) /// } /// # /// # fn main() { /// # my_function().unwrap(); /// # } /// ``` /// pub fn new(err: E) -> Self { SyncFailure { inner: Mutex::new(err), } } } impl Display for SyncFailure where T: Display, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.inner.lock().unwrap().fmt(f) } } impl Debug for SyncFailure where T: Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (*self.inner.lock().unwrap()).fmt(f) } } impl Fail for SyncFailure {}