Coverage Report

Created: 2026-09-14 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/snafu-0.9.2/src/whatever.rs
Line
Count
Source
1
use alloc::{boxed::Box, string::String};
2
3
use crate::{Backtrace, ChainCompat, Snafu};
4
5
/// A basic error type that you can use as a first step to better
6
/// error handling.
7
///
8
/// You can use this type in your own application as a quick way to
9
/// create errors or add basic context to another error. This can also
10
/// be used in a library, but consider wrapping it in an
11
/// [opaque](crate::guide::opaque) error to avoid putting the SNAFU
12
/// crate in your public API.
13
///
14
/// ## Examples
15
///
16
/// ```rust
17
/// use snafu::prelude::*;
18
///
19
/// type Result<T, E = snafu::Whatever> = std::result::Result<T, E>;
20
///
21
/// fn subtract_numbers(a: u32, b: u32) -> Result<u32> {
22
///     if a > b {
23
///         Ok(a - b)
24
///     } else {
25
///         whatever!("Can't subtract {a} - {b}")
26
///     }
27
/// }
28
///
29
/// fn complicated_math(a: u32, b: u32) -> Result<u32> {
30
///     let val = subtract_numbers(a, b).whatever_context("Can't do the math")?;
31
///     Ok(val * 2)
32
/// }
33
/// ```
34
///
35
/// See [`whatever!`][crate::whatever!] for detailed usage instructions.
36
///
37
/// ## Limitations
38
///
39
/// When wrapping errors, only the backtrace from the shallowest
40
/// function is guaranteed to be available. If you need the deepest
41
/// possible trace, consider creating a custom error type and [using
42
/// `#[snafu(backtrace)]` on the `source`
43
/// field](Snafu#controlling-backtraces). If a best-effort attempt is
44
/// sufficient, see the [`backtrace`][Self::backtrace] method.
45
///
46
/// When the standard library stabilizes support for the
47
/// [provide API](https://doc.rust-lang.org/std/error/trait.Error.html#method.provide),
48
/// this behavior may change.
49
///
50
/// ## Thread Safety
51
///
52
/// This type requires that contained errors implement [`Send`][] and
53
/// [`Sync`][]. If this is burdensome, you may also use
54
/// [`WhateverLocal`][].
55
#[derive(Debug, Snafu)]
56
#[snafu(crate_root(crate))]
57
#[snafu(whatever)]
58
#[snafu(display("{message}"))]
59
pub struct Whatever {
60
    #[snafu(source(from(Box<dyn crate::Error + Send + Sync>, Some)))]
61
    source: Option<Box<dyn crate::Error + Send + Sync>>,
62
    message: String,
63
    backtrace: Backtrace,
64
}
65
66
impl Whatever {
67
    /// Gets the backtrace from the deepest [`Whatever`][] or
68
    /// [`WhateverLocal`][] error. If none of the underlying errors
69
    /// are one of these types, returns the backtrace from when this
70
    /// instance was created.
71
0
    pub fn backtrace(&self) -> &Backtrace {
72
0
        known_whatevers_backtrace(self).unwrap_or(&self.backtrace)
73
0
    }
74
}
75
76
/// A basic error type that you can use as a first step to better
77
/// error handling when the error does not need to cross a thread
78
/// boundary.
79
///
80
/// This type behaves the same as [`Whatever`][] except it does not
81
/// require that the wrapped errors implement [`Send`][] or
82
/// [`Sync`][]. See [`Whatever`][] and [`whatever!`][crate::whatever!] for detailed
83
/// usage instructions.
84
#[derive(Debug, Snafu)]
85
#[snafu(crate_root(crate))]
86
#[snafu(whatever)]
87
#[snafu(display("{message}"))]
88
pub struct WhateverLocal {
89
    #[snafu(source(from(Box<dyn crate::Error>, Some)))]
90
    source: Option<Box<dyn crate::Error>>,
91
    message: String,
92
    backtrace: Backtrace,
93
}
94
95
impl WhateverLocal {
96
    /// Gets the backtrace from the deepest [`Whatever`][] or
97
    /// [`WhateverLocal`][] error. If none of the underlying errors
98
    /// are one of these types, returns the backtrace from when this
99
    /// instance was created.
100
0
    pub fn backtrace(&self) -> &Backtrace {
101
0
        known_whatevers_backtrace(self).unwrap_or(&self.backtrace)
102
0
    }
103
}
104
105
0
fn known_whatevers_backtrace<'a>(
106
0
    root: &'a (dyn crate::Error + 'static),
107
0
) -> Option<&'a crate::Backtrace> {
108
0
    ChainCompat::new(root)
109
0
        .skip(1)
110
0
        .filter_map(|e| {
111
0
            if let Some(e) = e.downcast_ref::<Whatever>() {
112
0
                Some(&e.backtrace)
113
0
            } else if let Some(e) = e.downcast_ref::<WhateverLocal>() {
114
0
                Some(&e.backtrace)
115
            } else {
116
0
                None
117
            }
118
0
        })
119
0
        .last()
120
0
}