Optional feature to wrap backtrace in an Arc to enable a full Clone impl

This commit is contained in:
Michael Pfaff 2023-07-01 12:58:07 -04:00
parent c945f1241e
commit 8a055af669
Signed by: michael
GPG Key ID: CF402C4A012AA9D4
3 changed files with 19 additions and 11 deletions

View File

@ -8,6 +8,7 @@ default = []
backtrace = [] backtrace = []
extra-backtrace = ["backtrace"] extra-backtrace = ["backtrace"]
clone-with-caveats = [] clone-with-caveats = []
arc-backtrace = []
termination = ["dep:ansee"] termination = ["dep:ansee"]
[dependencies] [dependencies]

View File

@ -10,7 +10,7 @@ use crate::report::report_write;
/// Provides context furthering the explanation of *how* you got to an error. /// Provides context furthering the explanation of *how* you got to an error.
#[derive(Debug)] #[derive(Debug)]
#[cfg_attr(feature = "clone-with-caveats", derive(Clone))] #[cfg_attr(any(feature = "arc-backtrace", feature = "clone-with-caveats"), derive(Clone))]
pub struct Context { pub struct Context {
pub(crate) detail: Detail, pub(crate) detail: Detail,
pub(crate) extra: Vec<Detail>, pub(crate) extra: Vec<Detail>,
@ -56,7 +56,7 @@ impl fmt::Display for Context {
} }
#[derive(Debug)] #[derive(Debug)]
#[cfg_attr(feature = "clone-with-caveats", derive(Clone))] #[cfg_attr(any(feature = "arc-backtrace", feature = "clone-with-caveats"), derive(Clone))]
#[non_exhaustive] #[non_exhaustive]
pub enum Detail { pub enum Detail {
Str(&'static str), Str(&'static str),
@ -76,7 +76,7 @@ impl Detail {
let bt = match bt.status() { let bt = match bt.status() {
Disabled => Backtrace::Disabled, Disabled => Backtrace::Disabled,
Unsupported => Backtrace::Unsupported, Unsupported => Backtrace::Unsupported,
status => Backtrace::Other(status, bt.to_string()), _ => Backtrace::Other(bt.into()),
}; };
Self::Backtrace(PrivateBacktrace(bt)) Self::Backtrace(PrivateBacktrace(bt))
} }
@ -87,22 +87,29 @@ pub struct PrivateError(pub(crate) Arc<dyn std::error::Error + Send + Sync>);
#[cfg(feature = "backtrace")] #[cfg(feature = "backtrace")]
#[derive(Debug)] #[derive(Debug)]
#[cfg_attr(feature = "clone-with-caveats", derive(Clone))] #[cfg_attr(any(feature = "arc-backtrace", feature = "clone-with-caveats"), derive(Clone))]
pub struct PrivateBacktrace(pub(crate) Backtrace); pub struct PrivateBacktrace(pub(crate) Backtrace);
// will be replaced with std::backtrace::Backtrace if and when it is Clone // will be replaced with std::backtrace::Backtrace if and when it is Clone
#[cfg(feature = "backtrace")] #[cfg(feature = "backtrace")]
#[derive(Debug)] #[derive(Debug)]
#[cfg_attr(feature = "arc-backtrace", derive(Clone))]
pub(crate) enum Backtrace { pub(crate) enum Backtrace {
Disabled, Disabled,
Unsupported, Unsupported,
Other(BacktraceStatus, String), #[cfg(feature = "arc-backtrace")]
Other(Arc<std::backtrace::Backtrace>),
#[cfg(not(feature = "arc-backtrace"))]
Other(std::backtrace::Backtrace),
} }
#[cfg(all(feature = "backtrace", feature = "clone-with-caveats"))] #[cfg(all(feature = "backtrace", feature = "clone-with-caveats", not(feature = "arc-backtrace")))]
impl Clone for Backtrace { impl Clone for Backtrace {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Backtrace::Disabled match self {
Self::Unsupported => Self::Unsupported,
_ => Self::Disabled
}
} }
} }
@ -117,8 +124,8 @@ impl fmt::Display for Detail {
#[cfg(feature = "backtrace")] #[cfg(feature = "backtrace")]
Self::Backtrace(PrivateBacktrace(Backtrace::Disabled)) => f.write_str("If you'd like a backtrace,\n try again with RUST_BACKTRACE=1"), Self::Backtrace(PrivateBacktrace(Backtrace::Disabled)) => f.write_str("If you'd like a backtrace,\n try again with RUST_BACKTRACE=1"),
#[cfg(feature = "backtrace")] #[cfg(feature = "backtrace")]
Self::Backtrace(PrivateBacktrace(Backtrace::Other(status, bt))) => { Self::Backtrace(PrivateBacktrace(Backtrace::Other(bt))) => {
f.write_str(if *status == BacktraceStatus::Captured { f.write_str(if bt.status() == BacktraceStatus::Captured {
"Here is the backtrace:\n" "Here is the backtrace:\n"
} else { } else {
"I can't tell if backtraces are working,\n but I'll give it a go:\n" "I can't tell if backtraces are working,\n but I'll give it a go:\n"

View File

@ -9,7 +9,7 @@ use crate::report::report_write;
/// By default, does not implement [`Clone`] because [`std::backtrace::Backtrace`] does not /// By default, does not implement [`Clone`] because [`std::backtrace::Backtrace`] does not
/// implement [`Clone`]. However, the `clone-with-caveats` feature may be used to enable a /// implement [`Clone`]. However, the `clone-with-caveats` feature may be used to enable a
/// [`Clone`] impl that sets the cloned `backtrace` to [`std::backtrace::Backtrace::disabled`]. /// [`Clone`] impl that sets the cloned `backtrace` to [`std::backtrace::Backtrace::disabled`].
#[cfg_attr(feature = "clone-with-caveats", derive(Clone))] #[cfg_attr(any(feature = "arc-backtrace", feature = "clone-with-caveats"), derive(Clone))]
pub struct How(Box<HowInner>); pub struct How(Box<HowInner>);
struct HowInner { struct HowInner {
@ -119,7 +119,7 @@ impl How {
} }
} }
#[cfg(feature = "clone-with-caveats")] #[cfg(any(feature = "arc-backtrace", feature = "clone-with-caveats"))]
impl Clone for HowInner { impl Clone for HowInner {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {