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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
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<T> { inner: Mutex<T>, } impl<E: Error + Send + 'static> SyncFailure<E> { /// 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<usize>, /// } /// /// // 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<T> Display for SyncFailure<T> where T: Display, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.inner.lock().unwrap().fmt(f) } } impl<T> Debug for SyncFailure<T> where T: Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.inner.lock().unwrap().fmt(f) } } impl<E: Error + Send + 'static> Fail for SyncFailure<E> {}