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 = []
extra-backtrace = ["backtrace"]
clone-with-caveats = []
arc-backtrace = []
termination = ["dep:ansee"]
[dependencies]

View File

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