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
//! The most common usage of SNAFU — an enumeration of possible errors.
//!
//! Start by looking at the error type [`Error`], then view the
//! *context selectors* [`Leaf`] and [`Intermediate`].

use crate::{Snafu, ResultExt};

/// An enumeration of possible errors.
///
/// This will create a number of *context selectors*:
///
/// - [`Leaf`]
/// - [`Intermediate`]
///
/// ## Leaf errors
///
/// Context selectors for error variants without a `source`, such
/// as `Leaf`, have methods to construct them, such as
/// [`Leaf::build`] or [`Leaf::fail`]. The [`ensure`] macro also
/// accepts these kinds of context selectors.
///
/// ```
/// # use snafu::guide::examples::basic::*;
/// use snafu::ensure;
///
/// fn always_fails() -> Result<(), Error> {
///     Leaf { user_id: 42 }.fail()
/// }
///
/// fn sometimes_fails(user_id: i32) -> Result<(), Error> {
///     ensure!(user_id > 0, Leaf { user_id });
///     Ok(())
/// }
/// ```
///
/// ## Intermediate errors
///
/// Context selectors for error variants with a `source`, such as
/// `Intermediate`, are intended to be used with the
/// [`ResultExt::context`] family of methods.
///
/// ```
/// # use snafu::guide::examples::basic::*;
/// use snafu::ResultExt;
///
/// fn load_config_file() -> Result<usize, Error> {
///     let config = std::fs::read_to_string("/path/to/my/config/file").context(Intermediate)?;
///     Ok(config.len())
/// }
/// ```
#[derive(Debug, Snafu)]
// This line is only needed to generate documentation; it is not
// needed in most cases:
#[snafu(crate_root(crate), visibility = "pub")]
pub enum Error {
    Leaf {
        user_id: i32,
    },

    Intermediate {
        source: std::io::Error,
    },
}