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
//! This crate aims to provide a convenient and lightweight way //! to clone errors and share them across thread-boundaries. //! //! It is designed to be used in conjunction with the //! [`failure`](https://crates.io/crates/failure) crate. //! //! # Example //! //! ```rust //! # extern crate failure; //! # extern crate shared_failure; //! # //! # use shared_failure::SharedFailure; //! # //! # fn main() { //! let custom_error = std::io::Error::new(std::io::ErrorKind::Other, "oh no!"); //! //! let shared_error = SharedFailure::from_fail(custom_error); //! //! // can be cloned, even though std::io::Error does not impl Clone //! let cloned_error = shared_error.clone(); //! //! assert_eq!(shared_error.to_string(), "oh no!"); //! assert_eq!(cloned_error.to_string(), "oh no!"); //! //! assert_eq!(shared_error.downcast_ref::<std::io::Error>().unwrap().kind(), //! std::io::ErrorKind::Other); //! # } //! ``` extern crate failure; use std::fmt::{Display, Formatter, Result as FmtResult}; use std::sync::Arc; use failure::{Backtrace, Error, Fail}; /// Failure that can be cloned and shared across thread boundaries. #[derive(Clone, Debug)] pub struct SharedFailure(Arc<Error>); impl SharedFailure { /// Wraps the provided error into a `SharedFailure`. pub fn from_fail<T: Fail>(err: T) -> SharedFailure { SharedFailure(Arc::new(err.into())) } /// Attempts to downcast this `SharedFailure` to a particular `Fail` type by reference. /// /// If the underlying error is not of type `T`, this will return [`None`](None()). pub fn downcast_ref<T: Fail>(&self) -> Option<&T> { self.0.downcast_ref() } } impl Fail for SharedFailure { fn cause(&self) -> Option<&Fail> { Some(self.0.cause()) } fn backtrace(&self) -> Option<&Backtrace> { Some(self.0.backtrace()) } } impl Display for SharedFailure { fn fmt(&self, f: &mut Formatter) -> FmtResult { self.0.fmt(f) } } impl From<Error> for SharedFailure { fn from(err: Error) -> SharedFailure { SharedFailure(Arc::new(err)) } }