/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 | } |