Support nested details, add with_backtrace method to IntoContext, impl IntoContext for Detail
This commit is contained in:
parent
184b334a09
commit
71385c9e19
|
@ -4,7 +4,8 @@ fn main0() -> Result<()> {
|
|||
Err(How::new(
|
||||
"The engine broke down"
|
||||
.with("Remember: you aren't good with cars")
|
||||
.with("Suggestion: call a tow truck"),
|
||||
.with("Suggestion: call a tow truck")
|
||||
.with("Foo".with("Bar").with("Baz")),
|
||||
)
|
||||
.context(
|
||||
"While driving down a road"
|
||||
|
|
|
@ -69,6 +69,7 @@ pub enum Detail {
|
|||
#[cfg(feature = "backtrace")]
|
||||
Backtrace(PrivateBacktrace),
|
||||
Error(PrivateError),
|
||||
Context(Box<Context>),
|
||||
}
|
||||
|
||||
impl Detail {
|
||||
|
@ -137,6 +138,7 @@ impl fmt::Display for Detail {
|
|||
write!(f, "{}", bt)
|
||||
},
|
||||
Self::Error(PrivateError(e)) => e.fmt(f),
|
||||
Self::Context(c) => c.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,6 +156,15 @@ pub trait IntoContext: Sized {
|
|||
fn with_caller(self) -> Context {
|
||||
self.with(Location::caller())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[track_caller]
|
||||
fn with_backtrace(self) -> Context {
|
||||
#[cfg(feature = "backtrace")]
|
||||
return self.with(Detail::backtrace());
|
||||
#[cfg(not(feature = "backtrace"))]
|
||||
self.into_context()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoContext for Context {
|
||||
|
@ -166,10 +177,12 @@ impl IntoContext for Context {
|
|||
#[track_caller]
|
||||
#[inline]
|
||||
fn with(mut self, other: impl IntoContext) -> Self {
|
||||
let mut other = other.into_context();
|
||||
self.extra.reserve(1 + other.extra.len());
|
||||
self.extra.push(other.detail);
|
||||
self.extra.append(&mut other.extra);
|
||||
let other = other.into_context();
|
||||
if other.extra.is_empty() {
|
||||
self.extra.push(other.detail);
|
||||
} else {
|
||||
self.extra.push(Detail::Context(other.into()));
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
@ -177,14 +190,14 @@ impl IntoContext for Context {
|
|||
impl IntoContext for String {
|
||||
#[inline(always)]
|
||||
fn into_context(self) -> Context {
|
||||
Context::new(Detail::String(self))
|
||||
Detail::String(self).into_context()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoContext for &'static str {
|
||||
#[inline(always)]
|
||||
fn into_context(self) -> Context {
|
||||
Context::new(Detail::Str(self))
|
||||
Detail::Str(self).into_context()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,7 +221,7 @@ impl<'a> IntoContext for &'a Location<'static> {
|
|||
impl IntoContext for Location<'static> {
|
||||
#[inline]
|
||||
fn into_context(self) -> Context {
|
||||
Context::new(Detail::Location(self))
|
||||
Detail::Location(self).into_context()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,14 +231,21 @@ where
|
|||
{
|
||||
#[inline]
|
||||
fn into_context(self) -> Context {
|
||||
Context::new(Detail::Error(PrivateError(self)))
|
||||
Detail::Error(PrivateError(self)).into_context()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoContext for Arc<dyn std::error::Error + Send + Sync> {
|
||||
#[inline]
|
||||
fn into_context(self) -> Context {
|
||||
Context::new(Detail::Error(PrivateError(self)))
|
||||
Detail::Error(PrivateError(self)).into_context()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoContext for Detail {
|
||||
#[inline(always)]
|
||||
fn into_context(self) -> Context {
|
||||
Context::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue