snafu/guide/examples/basic.rs
1//! The most common usage of SNAFU — an enumeration of possible errors.
2//!
3//! Start by looking at the error type [`Error`], then view the
4//! *context selectors* [`LeafSnafu`] and [`IntermediateSnafu`].
5
6use crate::prelude::*;
7
8/// An enumeration of possible errors.
9///
10/// This will create a number of *context selectors*:
11///
12/// - [`LeafSnafu`]
13/// - [`IntermediateSnafu`]
14///
15/// ## Leaf errors
16///
17/// Context selectors for error variants without a `source`, such
18/// as [`LeafSnafu`], have methods to construct them, such as
19/// [`LeafSnafu::build`] or [`LeafSnafu::fail`]. The [`ensure`] macro also
20/// accepts these kinds of context selectors.
21///
22/// ```
23/// # use snafu::guide::examples::basic::*;
24/// use snafu::prelude::*;
25///
26/// fn always_fails() -> Result<(), Error> {
27/// LeafSnafu { user_id: 42 }.fail()
28/// }
29///
30/// fn sometimes_fails(user_id: i32) -> Result<(), Error> {
31/// ensure!(user_id > 0, LeafSnafu { user_id });
32/// Ok(())
33/// }
34/// ```
35///
36/// ## Intermediate errors
37///
38/// Context selectors for error variants with a `source`, such as
39/// [`IntermediateSnafu`], are intended to be used with the
40/// [`ResultExt::context`] family of methods.
41///
42/// ```
43/// # use snafu::guide::examples::basic::*;
44/// use snafu::prelude::*;
45///
46/// fn load_config_file() -> Result<usize, Error> {
47/// let config = std::fs::read_to_string("/path/to/my/config/file").context(IntermediateSnafu)?;
48/// Ok(config.len())
49/// }
50/// ```
51///
52/// [`ResultExt::context`]: crate::ResultExt::context
53#[derive(Debug, Snafu)]
54// This line is only needed to generate documentation; it is not
55// needed in most cases:
56#[snafu(crate_root(crate), visibility(pub))]
57pub enum Error {
58 Leaf {
59 user_id: i32,
60 },
61
62 Intermediate {
63 source: std::io::Error,
64 },
65}