use std::backtrace::Backtrace; use super::*; /// Asserts that backtrace returned by `Error::backtrace` method equals/not-equals /// backtrace stored in object itself. /// /// Comparison is done by converting backtraces to strings /// and then comparing these strings. /// /// ## Syntax /// /// * Equals: `assert_bt!(==, ...)` /// * Not-equals: `assert_bt!(!=, ...)` /// /// ### Backtrace Access /// /// Shortcut for named-structs with `backtrace` field. /// Access backtrace as `error.backtrace`. /// /// ``` /// assert_bt!(==, error); /// ``` /// /// Full form for named- and tuple-structs. /// Access backtrace as `error.some_other_field` and `error.1` respectively. /// /// ``` /// assert_bt!(!=, error, some_other_field); /// assert_bt!(==, error, 1); /// ``` /// /// Access as a method call. /// Useful for enums (i.e., you can define a method that will match on enum variants /// and return backtrace for each variant). /// Access backtrace as `error.get_stored_backtrace_method()`. /// /// ``` /// assert_bt!(!=, error, .get_stored_backtrace_method); /// ``` macro_rules! assert_bt { (@impl $macro:ident, $error:expr, $backtrace:expr) => { $macro!(std::any::request_ref::(&$error).unwrap().to_string(), $backtrace.to_string()); }; (@expand $macro:ident, $error:expr, .$backtrace:ident) => { assert_bt!(@impl $macro, $error, $error.$backtrace()) }; (@expand $macro:ident, $error:expr, .$backtrace:tt) => { assert_bt!(@impl $macro, $error, $error.$backtrace) }; (@expand $macro:ident, $error:expr, $backtrace:ident) => { assert_bt!(@impl $macro, $error, $error.$backtrace) }; (@expand $macro:ident, $error:expr, $backtrace:expr) => { assert_bt!(@impl $macro, $error, $backtrace) }; (@expand $macro:ident, $error:expr) => { assert_bt!(@expand $macro, $error, backtrace) }; (==, $($args:tt)*) => { assert_bt!(@expand assert_eq, $($args)*) }; (!=, $($args:tt)*) => { assert_bt!(@expand assert_ne, $($args)*) }; } mod derives_for_enums_with_backtrace; mod derives_for_generic_enums_with_backtrace; mod derives_for_generic_structs_with_backtrace; mod derives_for_structs_with_backtrace; derive_display!(BacktraceErr); #[derive(Debug)] struct BacktraceErr { backtrace: Backtrace, } impl Default for BacktraceErr { fn default() -> Self { Self { backtrace: Backtrace::force_capture(), } } } impl Error for BacktraceErr { fn provide<'a>(&'a self, demand: &mut std::any::Demand<'a>) { demand .provide_ref::(&self.backtrace) .provide_value::(42); } }