use knowhow::{Context, Contextual};

#[derive(Debug, thiserror::Error)]
enum Error {
    #[error("failed: {0}")]
    Failed(&'static str),
}

fn fallible() -> Result<(), Error> {
    Err(Error::Failed("message"))
}

fn foo() -> Result<(), Contextual<Error>> {
    fallible()
        // when attaching more context, you need to help infer error type
        .context::<_, Error>("more context")
        .context("processing fallible function")?;

    Ok(())
}

fn foo_no_context() -> Result<(), Contextual<Error>> {
    fallible()?;
    Ok(())
}

fn main() {
    let e = foo().unwrap_err();
    std::assert_matches!(e.source(), Error::Failed("message"));
    println!("{e}");

    let e = foo_no_context().unwrap_err();
    std::assert_matches!(e.source(), Error::Failed("message"));
    println!("{e}");
}
