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");
9impl<'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 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 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}