n0_snafu/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
mod error;
mod spantrace;
pub use tracing_error::ErrorLayer;

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<Backtrace>,
    #[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<Backtrace>,
    }

    #[common_fields({
    backtrace: Option<Backtrace>,
    #[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<Backtrace>,
    #[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(())
    }
}