diff --git a/Cargo.lock b/Cargo.lock index ddd9bb1..e3a087c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,18 +64,40 @@ dependencies = [ "termcolor", ] +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "gimli" version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" + [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "indexmap" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -110,10 +132,23 @@ dependencies = [ "anyhow", "btparse", "color-backtrace", + "nested_enum_utils", "snafu", "tracing-error", ] +[[package]] +name = "nested_enum_utils" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43fa9161ed44d30e9702fe42bd78693bceac0fed02f647da749f36109023d3a3" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "object" version = "0.36.7" @@ -135,6 +170,15 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.93" @@ -187,7 +231,18 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.98", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] @@ -220,6 +275,23 @@ dependencies = [ "once_cell", ] +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "tracing" version = "0.1.41" @@ -347,3 +419,12 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +dependencies = [ + "memchr", +] diff --git a/Cargo.toml b/Cargo.toml index 23e58ce..f5eb221 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,6 @@ btparse = "0.2.0" color-backtrace = { version = "0.7.0", features = ["use-btparse-crate"] } snafu = { version = "0.8.5", features = ["rust_1_81", "std", "backtraces-impl-backtrace-crate"] } tracing-error = "0.2.1" + +[dev-dependencies] +nested_enum_utils = "0.2.2" diff --git a/src/lib.rs b/src/lib.rs index ec36d7e..31f1ad6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,3 +6,101 @@ pub use self::{ error::{Error, Result, ResultExt}, spantrace::SpanTrace, }; + +#[cfg(test)] +mod tests { + use super::*; + use nested_enum_utils::common_fields; + use snafu::{Backtrace, ErrorCompat, ResultExt, Snafu}; + + #[common_fields({ + backtrace: Option, + #[snafu(implicit)] + span_trace: SpanTrace, +})] + #[allow(missing_docs)] + #[derive(Debug, Snafu)] + #[non_exhaustive] + pub enum EnumNoTransparent { + #[snafu(display("This error wraps another enum"))] + WrapAnotherEnum { source: AnotherEnumError }, + #[snafu(display("This error wraps a struct"))] + WrapAStruct { source: StructError }, + } + + #[derive(Debug, Snafu)] + #[snafu(display("This is a struct error"))] + pub struct StructError { + backtrace: Option, + } + + #[common_fields({ + backtrace: Option, + #[snafu(implicit)] + span_trace: SpanTrace, +})] + #[allow(missing_docs)] + #[derive(Debug, Snafu)] + #[non_exhaustive] + pub enum EnumTransparent { + #[snafu(transparent)] + #[allow(dead_code)] + TransparentStruct { source: StructError }, + } + + #[common_fields({ + backtrace: Option, + #[snafu(implicit)] + span_trace: SpanTrace, +})] + #[allow(missing_docs)] + #[derive(Debug, Snafu)] + #[non_exhaustive] + pub enum AnotherEnumError { + #[snafu(display("This is a variant error in another enum"))] + ErrorInAnotherEnum {}, + } + + fn enum_no_transparent_another_enum() -> std::result::Result<(), EnumNoTransparent> { + another_enum().context(WrapAnotherEnumSnafu)?; + Ok(()) + } + + fn enum_no_transparent_struct() -> std::result::Result<(), EnumNoTransparent> { + struct_error().context(WrapAStructSnafu)?; + Ok(()) + } + + fn enum_transparent_struct() -> std::result::Result<(), EnumTransparent> { + struct_error()?; + Ok(()) + } + + fn struct_error() -> std::result::Result<(), StructError> { + let err = StructSnafu {}.build(); + println!("STRUCT BACKTRACE{:?}", err.backtrace()); + Err(err) + } + + fn another_enum() -> std::result::Result<(), AnotherEnumError> { + Err(ErrorInAnotherEnumSnafu {}.build()) + } + + #[test] + fn test_another_enum() -> Result<()> { + enum_no_transparent_another_enum()?; + Ok(()) + } + + #[test] + fn test_wrap_a_struct() -> Result<()> { + enum_no_transparent_struct()?; + Ok(()) + } + + #[test] + fn test_transparent() -> Result<()> { + enum_transparent_struct()?; + Ok(()) + } +}