lazy_wrap/
lazy_wrap.rs

1//! Use lazy evaluation to wrap errors in more context.
2//!
3//! Will print (with colors):
4//!
5//! ```console
6//! error: unable to load data from file: `/not/an/exsisting/file`
7//! cause: file not found: /not/an/exsisting/file
8//! cause: No such file or directory (os error 2)
9//! ```
10
11use std::{
12    fs,
13    path::{Path, PathBuf},
14};
15
16use narrate::{report, CliError, ErrorWrap, ExitCode, Result};
17
18fn main() {
19    let path = PathBuf::from("/not/an/exsisting/file");
20    let res = run(path);
21
22    if let Err(ref err) = res {
23        report::err_full(err);
24        std::process::exit(err.exit_code());
25    }
26}
27
28fn run(path: PathBuf) -> Result<()> {
29    // lazily create context string
30    let _ = load_data(&path)
31        .wrap_with(|| format!("unable to load data from file: `{}`", path.display()))?;
32    Ok(())
33}
34
35fn load_data(path: &Path) -> Result<String> {
36    // lazily create CliError
37    let contents =
38        fs::read_to_string(path).wrap_with(|| CliError::InputFileNotFound(path.to_owned()))?;
39
40    // lazily create context string
41    let data =
42        parse(&contents).wrap_with(|| format!("unable to parse file: `{}`", path.display()))?;
43
44    Ok(data)
45}
46
47fn parse(raw: &str) -> Result<String> {
48    // fake parsing
49    Ok(raw.to_ascii_lowercase())
50}