1use std::error::Error as StdError;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
6pub enum NeverErr {}
7
8impl std::fmt::Display for NeverErr {
9 fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match *self {} }
10}
11
12impl std::error::Error for NeverErr {}
13
14#[derive(Debug, PartialEq, Eq, Clone)]
16pub enum FatalError<E> {
17 Error(E),
19 Fatal(E),
21}
22
23impl<E> FatalError<E> {
24 pub fn is_error(&self) -> bool { matches!(self, FatalError::Error(_)) }
26
27 pub fn is_fatal(&self) -> bool { matches!(self, FatalError::Fatal(_)) }
29
30 pub fn into_inner(self) -> E {
32 match self {
33 FatalError::Error(x) => x,
34 FatalError::Fatal(x) => x,
35 }
36 }
37
38 pub fn map<E2, F>(self, f: F) -> FatalError<E2>
40 where
41 F: FnOnce(E) -> E2,
42 {
43 match self {
44 FatalError::Error(x) => FatalError::Error(f(x)),
45 FatalError::Fatal(x) => FatalError::Fatal(f(x)),
46 }
47 }
48
49 pub fn escalate(self) -> Self { FatalError::Fatal(self.into_inner()) }
51
52 pub fn deescalate(self) -> Self { FatalError::Error(self.into_inner()) }
54
55 pub fn fatality(self) -> Result<E, Self> {
57 match self {
58 FatalError::Error(x) => Ok(x),
59 x @ FatalError::Fatal(_) => Err(x),
60 }
61 }
62
63 pub fn recover(self) -> Result<E, E> {
65 match self {
66 FatalError::Error(x) => Ok(x),
67 FatalError::Fatal(x) => Err(x),
68 }
69 }
70
71 pub fn map_error<T, F>(self, f: F) -> Result<T, Self>
73 where
74 F: FnOnce(E) -> Result<T, Self>,
75 {
76 match self {
77 FatalError::Error(x) => f(x),
78 x @ FatalError::Fatal(_) => Err(x),
79 }
80 }
81
82 pub fn map_fatal<T, F>(self, f: F) -> Result<T, Self>
84 where
85 F: FnOnce(E) -> Result<T, Self>,
86 {
87 match self {
88 x @ FatalError::Error(_) => Err(x),
89 FatalError::Fatal(x) => f(x),
90 }
91 }
92
93 pub fn then<T, F>(self, f: F) -> Result<T, Self>
95 where
96 F: FnOnce(E) -> Result<T, Self>,
97 {
98 f(self.into_inner())
99 }
100}
101
102impl<E: std::fmt::Display> std::fmt::Display for FatalError<E> {
103 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104 match self {
105 FatalError::Error(x) => write!(f, "Error: {x}"),
106 FatalError::Fatal(x) => write!(f, "Fatal Error: {x}"),
107 }
108 }
109}
110
111impl<E: StdError + 'static> StdError for FatalError<E> {
112 fn source(&self) -> Option<&(dyn StdError + 'static)> {
113 match self {
114 FatalError::Error(x) | FatalError::Fatal(x) => x.source(),
115 }
116 }
117}