Skip to content

Commit

Permalink
Split GenerateBacktrace into two traits to allow reuse
Browse files Browse the repository at this point in the history
  • Loading branch information
shepmaster committed Sep 25, 2021
1 parent addb824 commit 7ece503
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 25 deletions.
24 changes: 12 additions & 12 deletions snafu-derive/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ pub mod context_selector {
.collect()
}

fn construct_backtrace_field(&self) -> Option<TokenStream> {
fn construct_implicit_fields(&self) -> Option<TokenStream> {
self.backtrace_field.map(|field| {
let crate_root = self.crate_root;
let name = &field.name;
quote! { #name: #crate_root::GenerateBacktrace::generate(), }
quote! { #name: #crate_root::GenerateImplicitData::generate(), }
})
}

Expand Down Expand Up @@ -165,7 +165,7 @@ pub mod context_selector {
let visibility = self.visibility;
let extended_where_clauses = self.extended_where_clauses();
let transfer_user_fields = self.transfer_user_fields();
let construct_backtrace_field = self.construct_backtrace_field();
let construct_implicit_fields = self.construct_implicit_fields();

quote! {
impl<#(#user_field_generics,)*> #parameterized_selector_name {
Expand All @@ -176,7 +176,7 @@ pub mod context_selector {
#(#extended_where_clauses),*
{
#error_constructor_name {
#construct_backtrace_field
#construct_implicit_fields
#(#transfer_user_fields,)*
}
}
Expand All @@ -201,7 +201,7 @@ pub mod context_selector {
let user_field_generics = self.user_field_generics();
let extended_where_clauses = self.extended_where_clauses();
let transfer_user_fields = self.transfer_user_fields();
let construct_backtrace_field = self.construct_backtrace_field();
let construct_implicit_fields = self.construct_implicit_fields();

let (source_ty, transfer_source_field) = match source_field {
Some(source_field) => {
Expand All @@ -222,7 +222,7 @@ pub mod context_selector {
fn into_error(self, error: Self::Source) -> #parameterized_error_name {
#error_constructor_name {
#transfer_source_field
#construct_backtrace_field
#construct_implicit_fields
#(#transfer_user_fields),*
}
}
Expand All @@ -238,7 +238,7 @@ pub mod context_selector {
let crate_root = self.crate_root;
let parameterized_error_name = self.parameterized_error_name;
let error_constructor_name = self.error_constructor_name;
let construct_backtrace_field = self.construct_backtrace_field();
let construct_implicit_fields = self.construct_implicit_fields();

// testme: transform

Expand Down Expand Up @@ -267,15 +267,15 @@ pub mod context_selector {
#error_constructor_name {
#empty_source_field
#message_field_name: message,
#construct_backtrace_field
#construct_implicit_fields
}
}

fn with_source(error: Self::Source, message: String) -> Self {
#error_constructor_name {
#transfer_source_field
#message_field_name: message,
#construct_backtrace_field
#construct_implicit_fields
}
}
}
Expand All @@ -285,7 +285,7 @@ pub mod context_selector {
fn generate_from_source(self, source_field: &crate::SourceField) -> TokenStream {
let parameterized_error_name = self.parameterized_error_name;
let error_constructor_name = self.error_constructor_name;
let construct_backtrace_field = self.construct_backtrace_field();
let construct_implicit_fields = self.construct_implicit_fields();
let original_generics_without_defaults = self.original_generics_without_defaults;
let user_field_generics = self.user_field_generics();
let where_clauses = self.where_clauses;
Expand All @@ -300,7 +300,7 @@ pub mod context_selector {
fn from(error: #source_field_type) -> Self {
#error_constructor_name {
#transfer_source_field
#construct_backtrace_field
#construct_implicit_fields
}
}
}
Expand Down Expand Up @@ -633,7 +633,7 @@ pub mod error_compat {
name: field_name, ..
} = backtrace_field;
quote! {
#pattern_ident { ref #field_name, .. } => { #crate_root::GenerateBacktrace::as_backtrace(#field_name) }
#pattern_ident { ref #field_name, .. } => { #crate_root::AsBacktrace::as_backtrace(#field_name) }
}
}
_ => {
Expand Down
4 changes: 3 additions & 1 deletion src/backtrace_inert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ use core::fmt;
#[derive(Debug)]
pub struct Backtrace(());

impl crate::GenerateBacktrace for Backtrace {
impl crate::GenerateImplicitData for Backtrace {
fn generate() -> Self {
Backtrace(())
}
}

impl crate::AsBacktrace for Backtrace {
fn as_backtrace(&self) -> Option<&Backtrace> {
Some(self)
}
Expand Down
4 changes: 3 additions & 1 deletion src/backtrace_shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ use std::{fmt, path};
#[derive(Debug)]
pub struct Backtrace(backtrace::Backtrace);

impl crate::GenerateBacktrace for Backtrace {
impl crate::GenerateImplicitData for Backtrace {
// Inlining in an attempt to remove this function from the backtrace
#[inline(always)]
fn generate() -> Self {
Backtrace(backtrace::Backtrace::new())
}
}

impl crate::AsBacktrace for Backtrace {
fn as_backtrace(&self) -> Option<&Backtrace> {
Some(self)
}
Expand Down
10 changes: 5 additions & 5 deletions src/guide/examples/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! Start by looking at the error type [`Error`].
use crate::{Snafu, Backtrace, ErrorCompat, GenerateBacktrace};
use crate::{Snafu, Backtrace, ErrorCompat, GenerateImplicitData};

/// Backtraces aren't yet supported by the stable Rust compiler. SNAFU
/// provides a stable-compatible way of getting backtraces as well as
Expand Down Expand Up @@ -70,10 +70,10 @@ pub enum Error {

/// When an error is expected to be created frequently but the
/// backtrace is rarely needed, you can wrap it in an
/// `Option`. See
/// [GenerateBacktrace](GenerateBacktrace#impl-GenerateBacktrace-for-Option<Backtrace>)
/// for instructions on how to access the backtrace in this
/// case.
/// `Option`. See [the instructions][] on how to access the
/// backtrace in this case.
///
/// [the instructions]: GenerateImplicitData#impl-GenerateImplicitData-for-Option<Backtrace>
UsedInTightLoop {
backtrace: Option<Backtrace>,
},
Expand Down
25 changes: 19 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1020,11 +1020,15 @@ pub trait FromString {
fn with_source(source: Self::Source, message: String) -> Self;
}

/// Construct a backtrace, allowing it to be optional.
pub trait GenerateBacktrace {
/// Generate a new backtrace instance
/// Construct data to be included as part of an error. The data must
/// require no arguments to be created.
pub trait GenerateImplicitData {
/// Build the data.
fn generate() -> Self;
}

/// View a backtrace-like value as an optional backtrace.
pub trait AsBacktrace {
/// Retrieve the optional backtrace
fn as_backtrace(&self) -> Option<&Backtrace>;
}
Expand All @@ -1039,7 +1043,7 @@ pub trait GenerateBacktrace {
/// changing the environment variable after it has been checked will
/// have no effect.
#[cfg(any(feature = "std", test))]
impl GenerateBacktrace for Option<Backtrace> {
impl GenerateImplicitData for Option<Backtrace> {
fn generate() -> Self {
use std::env;
use std::sync::{
Expand All @@ -1064,29 +1068,38 @@ impl GenerateBacktrace for Option<Backtrace> {
None
}
}
}

#[cfg(any(feature = "std", test))]
impl AsBacktrace for Option<Backtrace> {
fn as_backtrace(&self) -> Option<&Backtrace> {
self.as_ref()
}
}

#[cfg(feature = "backtraces-impl-backtrace-crate")]
impl GenerateBacktrace for Backtrace {
impl GenerateImplicitData for Backtrace {
fn generate() -> Self {
Backtrace::new()
}
}

#[cfg(feature = "backtraces-impl-backtrace-crate")]
impl AsBacktrace for Backtrace {
fn as_backtrace(&self) -> Option<&Backtrace> {
Some(self)
}
}

#[cfg(feature = "unstable-backtraces-impl-std")]
impl GenerateBacktrace for Backtrace {
impl GenerateImplicitData for Backtrace {
fn generate() -> Self {
Backtrace::force_capture()
}
}

#[cfg(feature = "unstable-backtraces-impl-std")]
impl AsBacktrace for Backtrace {
fn as_backtrace(&self) -> Option<&Backtrace> {
Some(self)
}
Expand Down

0 comments on commit 7ece503

Please sign in to comment.