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(
|
Err(How::new(
|
||||||
"The engine broke down"
|
"The engine broke down"
|
||||||
.with("Remember: you aren't good with cars")
|
.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(
|
.context(
|
||||||
"While driving down a road"
|
"While driving down a road"
|
||||||
|
|
|
@ -69,6 +69,7 @@ pub enum Detail {
|
||||||
#[cfg(feature = "backtrace")]
|
#[cfg(feature = "backtrace")]
|
||||||
Backtrace(PrivateBacktrace),
|
Backtrace(PrivateBacktrace),
|
||||||
Error(PrivateError),
|
Error(PrivateError),
|
||||||
|
Context(Box<Context>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Detail {
|
impl Detail {
|
||||||
|
@ -137,6 +138,7 @@ impl fmt::Display for Detail {
|
||||||
write!(f, "{}", bt)
|
write!(f, "{}", bt)
|
||||||
},
|
},
|
||||||
Self::Error(PrivateError(e)) => e.fmt(f),
|
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 {
|
fn with_caller(self) -> Context {
|
||||||
self.with(Location::caller())
|
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 {
|
impl IntoContext for Context {
|
||||||
|
@ -166,10 +177,12 @@ impl IntoContext for Context {
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with(mut self, other: impl IntoContext) -> Self {
|
fn with(mut self, other: impl IntoContext) -> Self {
|
||||||
let mut other = other.into_context();
|
let other = other.into_context();
|
||||||
self.extra.reserve(1 + other.extra.len());
|
if other.extra.is_empty() {
|
||||||
self.extra.push(other.detail);
|
self.extra.push(other.detail);
|
||||||
self.extra.append(&mut other.extra);
|
} else {
|
||||||
|
self.extra.push(Detail::Context(other.into()));
|
||||||
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,14 +190,14 @@ impl IntoContext for Context {
|
||||||
impl IntoContext for String {
|
impl IntoContext for String {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn into_context(self) -> Context {
|
fn into_context(self) -> Context {
|
||||||
Context::new(Detail::String(self))
|
Detail::String(self).into_context()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoContext for &'static str {
|
impl IntoContext for &'static str {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn into_context(self) -> Context {
|
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> {
|
impl IntoContext for Location<'static> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_context(self) -> Context {
|
fn into_context(self) -> Context {
|
||||||
Context::new(Detail::Location(self))
|
Detail::Location(self).into_context()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,14 +231,21 @@ where
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_context(self) -> Context {
|
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> {
|
impl IntoContext for Arc<dyn std::error::Error + Send + Sync> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_context(self) -> Context {
|
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