Revision control

Copy as Markdown

Other Tools

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::<Backtrace>(&$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::<Backtrace>(&self.backtrace)
.provide_value::<i32>(42);
}
}