thistrace 0.1.0

Callsite provenance (file/line/col) for thiserror #[from] conversions via #[track_caller]
Documentation
use thistrace::{origin, traceable, OneLineTrace};

#[derive(thiserror::Error, Debug)]
#[error("leaf boom")]
struct LeafError;

#[traceable]
#[derive(thiserror::Error, Debug)]
enum AppError {
    #[error("leaf")]
    Leaf(#[from] thistrace::Origin<LeafError>),
}

fn make_leaf() -> Result<(), thistrace::Origin<LeafError>> {
    Err(origin(LeafError))
}

fn layer1() -> Result<(), AppError> {
    make_leaf()?;
    Ok(())
}

fn layer2() -> Result<(), thistrace::Bubbled<AppError>> {
    layer1().map_err(thistrace::bubble_err!())?;
    Ok(())
}

fn layer3() -> Result<(), thistrace::Bubbled<AppError>> {
    layer2().map_err(thistrace::rebubble_err!())?;
    Ok(())
}

#[test]
fn single_enum_no_recursive_variant_can_still_accumulate_frames() {
    let err = layer3().unwrap_err();
    let frames = thistrace::trace_frames(&err);

    // origin + layer1 conversion + layer2 bubble + layer3 bubble
    assert!(frames.len() >= 4);

    let one_line = format!("{}", OneLineTrace::new(&err));
    assert!(!one_line.contains('\n'));
}