sfwtools/
error.rs

1use std::fmt::{self, Display};
2use std::io::{Error, ErrorKind::*};
3use std::process;
4
5const USER_ERROR_CODE: i32 = 1;
6
7pub struct NoneErrorRich<'a>(&'a str);
8const NONE_ERROR_DEFAULT: NoneErrorRich = NoneErrorRich("Can't unwrap None");
9//
10impl<'a> fmt::Display for NoneErrorRich<'a> {
11    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12        write!(f, "{}", self.0)
13    }
14}
15
16pub fn user_exit(msg: &str) {
17    eprintln!("{}", msg);
18    process::exit(USER_ERROR_CODE)
19}
20
21pub trait SfwRes<T, E: Display> {
22    fn unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T;
23
24    /// Intended for use late in execution (e.g. in binaries),
25    /// so that the program immediately exits with a user-friendly error message.
26    fn user_err(self, fstr: &str) -> T
27    where
28        Self: Sized,
29    {
30        self.unwrap_or_else(|err| {
31            eprintln!("{}: {}", fstr, err);
32            process::exit(USER_ERROR_CODE)
33        })
34    }
35}
36
37impl<T, E: Display> SfwRes<T, E> for Result<T, E> {
38    fn unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T {
39        self.unwrap_or_else(op)
40    }
41}
42
43impl<'a, T> SfwRes<T, NoneErrorRich<'a>> for Option<T> {
44    fn unwrap_or_else<F: FnOnce(NoneErrorRich<'a>) -> T>(self, op: F) -> T {
45        self.unwrap_or_else(|| op(NONE_ERROR_DEFAULT))
46    }
47}
48
49pub trait SfwResError<T> {
50    /// Intended as a potentially non-fatal error, typically
51    /// used in library code.
52    fn sfw_err(self, fstr: &str) -> Result<T, Error>
53    where
54        Self: Sized;
55}
56
57impl<T> SfwResError<T> for Result<T, Error> {
58    fn sfw_err(self, fstr: &str) -> Result<T, Error> {
59        self.map_err(|err| {
60            Error::new(Error::kind(&err), format!("{}: {}", fstr, err))
61        })
62    }
63}
64
65impl<T> SfwResError<T> for Option<T> {
66    fn sfw_err(self, fstr: &str) -> Result<T, Error> {
67        match self {
68            Some(s) => Ok(s),
69            None => Err(Error::new(NotFound, fstr)),
70        }
71    }
72}