diff --git a/src/context.rs b/src/context.rs index bc55a70..49a82af 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,6 +1,6 @@ use std::backtrace::Backtrace; -use std::fmt::{self, Debug, Display}; use std::error::Error; +use std::fmt::{self, Debug, Display}; use crate::Exception; @@ -10,7 +10,8 @@ pub trait Context { fn context(self, context: C) -> Result; /// Wrap the error value with additional context lazily. - fn with_context(self, f: F) -> Result where + fn with_context(self, f: F) -> Result + where C: Display + Send + Sync + 'static, F: FnOnce(&E) -> C; } @@ -20,11 +21,17 @@ impl Context for Result { self.map_err(|error| Exception::from(ContextError { error, context })) } - fn with_context(self, f: F) -> Result where + fn with_context(self, f: F) -> Result + where C: Display + Send + Sync + 'static, - F: FnOnce(&E) -> C + F: FnOnce(&E) -> C, { - self.map_err(|error| Exception::from(ContextError { context: f(&error), error })) + self.map_err(|error| { + Exception::from(ContextError { + context: f(&error), + error, + }) + }) } } @@ -33,11 +40,17 @@ impl Context for Result { self.map_err(|error| Exception::from(ContextError { error, context })) } - fn with_context(self, f: F) -> Result where + fn with_context(self, f: F) -> Result + where C: Display + Send + Sync + 'static, - F: FnOnce(&Exception) -> C + F: FnOnce(&Exception) -> C, { - self.map_err(|error| Exception::from(ContextError { context: f(&error), error })) + self.map_err(|error| { + Exception::from(ContextError { + context: f(&error), + error, + }) + }) } } diff --git a/src/exception.rs b/src/exception.rs index af9164f..9134d70 100644 --- a/src/exception.rs +++ b/src/exception.rs @@ -26,32 +26,40 @@ impl Exception { /// /// If the error type does not provide a backtrace, a backtrace will be created here to ensure /// that a backtrace exists. - pub fn new(error: E) -> Exception where - E: Error + Send + Sync + 'static + pub fn new(error: E) -> Exception + where + E: Error + Send + Sync + 'static, { Exception::construct(error, TypeId::of::()) } #[doc(hidden)] - pub fn new_adhoc(message: M) -> Exception where - M: Display + Debug + Send + Sync + 'static + pub fn new_adhoc(message: M) -> Exception + where + M: Display + Debug + Send + Sync + 'static, { Exception::construct(MessageError(message), TypeId::of::()) } - fn construct(error: E, type_id: TypeId) -> Exception where + fn construct(error: E, type_id: TypeId) -> Exception + where E: Error + Send + Sync + 'static, { unsafe { let backtrace = match error.backtrace() { Some(_) => None, - None => Some(Backtrace::capture()), + None => Some(Backtrace::capture()), }; let obj: TraitObject = mem::transmute(&error as &dyn Error); let vtable = obj.vtable; - let inner = InnerException { vtable, type_id, backtrace, error }; + let inner = InnerException { + vtable, + type_id, + backtrace, + error, + }; Exception { - inner: mem::transmute(Box::new(inner)) + inner: mem::transmute(Box::new(inner)), } } } @@ -70,7 +78,10 @@ impl Exception { pub fn backtrace(&self) -> &Backtrace { // NB: this unwrap can only fail if the underlying error's backtrace method is // nondeterministic, which would only happen in maliciously constructed code - self.inner.backtrace.as_ref().or_else(|| self.inner.error().backtrace()) + self.inner + .backtrace + .as_ref() + .or_else(|| self.inner.error().backtrace()) .expect("exception backtrace capture failed") } @@ -79,7 +90,9 @@ impl Exception { /// This iterator will visit every error in the "cause chain" of this exception, beginning with /// the error that this exception was created from. pub fn errors(&self) -> Errors<'_> { - Errors { next: Some(self.inner.error()) } + Errors { + next: Some(self.inner.error()), + } } /// Returns `true` if `E` is the type wrapped by this exception. @@ -105,14 +118,18 @@ impl Exception { pub fn downcast_ref(&self) -> Option<&E> { if self.is::() { unsafe { Some(&*(self.inner.error() as *const dyn Error as *const E)) } - } else { None } + } else { + None + } } /// Downcast this exception by mutable reference. pub fn downcast_mut(&mut self) -> Option<&mut E> { if self.is::() { unsafe { Some(&mut *(self.inner.error_mut() as *mut dyn Error as *mut E)) } - } else { None } + } else { + None + } } } @@ -152,14 +169,17 @@ impl Debug for Exception { let backtrace = self.backtrace(); match backtrace.status() { - BacktraceStatus::Captured => { + BacktraceStatus::Captured => { writeln!(f, "\n{}", backtrace)?; } - BacktraceStatus::Disabled => { - writeln!(f, "\nbacktrace disabled; run with RUST_BACKTRACE=1 environment variable \ - to display a backtrace")?; + BacktraceStatus::Disabled => { + writeln!( + f, + "\nbacktrace disabled; run with RUST_BACKTRACE=1 environment variable \ + to display a backtrace" + )?; } - _ => { } + _ => {} } Ok(()) @@ -172,8 +192,8 @@ impl Display for Exception { } } -unsafe impl Send for Exception { } -unsafe impl Sync for Exception { } +unsafe impl Send for Exception {} +unsafe impl Sync for Exception {} impl Drop for Exception { fn drop(&mut self) { @@ -212,7 +232,7 @@ impl Display for MessageError { } } -impl Error for MessageError { } +impl Error for MessageError {} impl InnerException<()> { fn error(&self) -> &(dyn Error + Send + Sync + 'static) { @@ -241,6 +261,7 @@ pub struct Errors<'a> { impl<'a> Iterator for Errors<'a> { type Item = &'a (dyn Error + 'static); + fn next(&mut self) -> Option { let next = self.next.take()?; self.next = next.source(); @@ -252,24 +273,28 @@ impl<'a> Iterator for Errors<'a> { mod repr_correctness { use super::*; - use std::mem; use std::marker::Unpin; + use std::mem; #[test] fn size_of_exception() { assert_eq!(mem::size_of::(), mem::size_of::()); } - #[allow(dead_code)] fn assert_exception_autotraits() where - Exception: Unpin + Send + Sync + 'static - { } + #[allow(dead_code)] + fn assert_exception_autotraits() + where + Exception: Unpin + Send + Sync + 'static, + { + } #[test] fn destructors_work() { use std::sync::*; - #[derive(Debug)] struct HasDrop(Box>>); - impl Error for HasDrop { } + #[derive(Debug)] + struct HasDrop(Box>>); + impl Error for HasDrop {} impl Display for HasDrop { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "does something") @@ -288,6 +313,5 @@ mod repr_correctness { drop(Exception::from(HasDrop(Box::new(has_dropped.clone())))); assert!(*has_dropped.lock().unwrap()); - } } diff --git a/src/lib.rs b/src/lib.rs index cd4df3a..18ee921 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,19 +1,21 @@ #![feature(backtrace)] mod as_error; -mod exception; mod context; +mod exception; pub use crate::as_error::AsError; -pub use crate::exception::{Exception, Errors}; pub use crate::context::Context; +pub use crate::exception::{Errors, Exception}; /// Throw an error. /// /// This macro is equivalent to `Err($err)?`. #[macro_export] macro_rules! throw { - ($err:expr) => (return std::result::Result::Err(std::convert::From::from($err))) + ($err:expr) => { + return std::result::Result::Err(std::convert::From::from($err)); + }; } /// Construct an ad-hoc exception from a string.