1use camino::Utf8PathBuf;
2use compact_str::{CompactString, ToCompactString};
3
4#[feature("serde_feature")]
5use serde::{Deserialize, Serialize};
6use std::{convert::Infallible, error::Error, fmt::Display, io::Stderr, process::{ExitCode, Termination}, time::Instant};
7
8#[cfg_attr(feature = "serde_feature", derive(Deserialize, Serialize))]
46#[derive(PartialEq, PartialOrd, Ord, Eq, Debug, Clone)]
47pub enum Catastrophe {
48 Error {
49 description: CompactString,
50 source: Option<Box<Catastrophe>>,
52 },
53}
54
55unsafe impl Send for Catastrophe {}
56
57unsafe impl Sync for Catastrophe {}
58
59
60impl Catastrophe {
61 pub fn new_error(description: CompactString, source: Option<Box<Catastrophe>>) -> Self {
62 Self::Error{description, source}
63 }
64
65 pub fn g<S: AsRef<str>>(description: S) -> Self {
67 Self::new_error(description.as_ref().to_compact_string(), None)
68 }
69
70 pub fn description(&self) -> CompactString {
72 match self {
73 Catastrophe::Error { description, source } => {
74 match source {
75 Some(inner) => inner.to_string().into(),
76 None => description.clone(),
77 }
78 }
79 }
80 }
81}
82
83
84impl<E: Error> From<E> for Catastrophe {
85 fn from(value: E) -> Self {
86 let source = value.source().map(|er| Box::new(Catastrophe::from(er)));
87 let description = value.to_compact_string();
88 Self::new_error(description, source)
89 }
90}
91
92
93impl From<Catastrophe> for Box<dyn Error + Send + Sync> {
94 fn from(value: Catastrophe) -> Self {
95 match value {
96 Catastrophe::Error { description, .. } => {
97 Box::<dyn Error + Send + Sync>::from(description.to_string())
98 },
99 }
100
101 }
102}
103
104
105impl From<Catastrophe> for ExitCode {
106 fn from(value: Catastrophe) -> Self {
107 match value {
108 Catastrophe::Error { description: _, source: _ } => Self::FAILURE,
109 }
110 }
111}
112
113impl Termination for Catastrophe {
114 fn report(self) -> ExitCode {
115 self.into()
116 }
117}
118
119impl Display for Catastrophe {
120 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121 match self {
122 Catastrophe::Error { description, source } => {
123 match source {
124 Some(c) => {
125 write!(f, "{}", c.description())
127 }
128 None => {
129 write!(f, "{}", description)
130 }
131 }
132 }
133 }
134
135 }
136}
137
138pub struct ErrCode(u16);
139
140impl ErrCode {
141 pub fn new(n: u16) -> Self {
142 Self(n)
143 }
144
145 pub fn from_hex_str<S: AsRef<str>>(s: S) -> Res<Self> {
146 let hex = u16::from_str_radix(s.as_ref(), 16)?;
147 Ok(Self::new(hex))
148 }
149
150 pub fn unknown_error() -> Self {
152 Self::new(u16::MAX)
153 }
154}
155
156impl<E: Error> From<E> for ErrCode {
157 fn from(_: E) -> Self {
158 Self::unknown_error()
159 }
160}
161
162pub type Empty = ();
164
165pub type Res<T> = Result<T, Catastrophe>;
166
167pub type ResE = Res<Empty>;
169
170pub type Maybe<T> = Option<T>;
172
173#[cfg_attr(feature = "serde_feature", derive(Deserialize, Serialize))]
175#[derive(Clone, PartialEq, PartialOrd, Default)]
176pub struct Optional<D: Default>(D);
177
178#[derive(Clone, PartialEq, PartialOrd, Hash)]
181pub struct Isfet {
182 instant: Instant,
183 explanation: CompactString,
184 child: Option<Box<Self>>,
185}
186
187impl Isfet {
188 pub fn new(instant: Instant, explanation: CompactString, child: Option<Box<Self>>) -> Self {
189 Self {
190 instant,
191 explanation,
192 child,
193 }
194 }
195 pub fn to_vec(self) -> Vec<Self> {
196 let mut out = vec![self.clone()];
197 let mut rest: Vec<_> = self.into_iter().collect();
198 out.append(&mut rest);
199 out
200 }
201}
202
203impl Display for Isfet {
204 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
205 if let Some(child) = &self.child {
206 write!(f, "{:#?}|{}\n{}", self.instant, self.explanation, child)
207 } else {
208 write!(f, "{:#?}|{}", self.instant, self.explanation)
209 }
210 }
211}
212
213impl Iterator for Isfet {
215 type Item = Self;
216
217 fn next(&mut self) -> Option<Self::Item> {
218 if let Some(n) = &self.child {
219 let c = n.clone();
220 Some(*c)
221 } else {
222 None
223 }
224 }
225}
226
227
228impl<E: Error> From<E> for Isfet {
242 fn from(value: E) -> Self {
243 let instant = Instant::now();
244 if let Some(child_err) = value.source() {
245 let child: Isfet = child_err.into();
246 Isfet::new(instant, value.to_compact_string(), Some(Box::new(child)))
247 } else {
248 Isfet::new(instant, value.to_compact_string(), None)
249 }
250 }
251}
252
253pub trait Disorder {
254 fn from_infalliable(i: Infallible) -> Self;
255 fn from_stderror(s: Stderr) -> Self;
256
257 fn to_infalliable(&self) -> Infallible;
258 fn to_stderror(&self) -> Stderr;
259
260}
261
262#[feature("serde_feature")]
263#[derive(Deserialize, Serialize)]
264#[derive(PartialEq, PartialOrd)]
265pub enum Either<L, R> {
266 Left(L),
267 Right(R),
268}
269
270impl<L, R> Either<L, R> {
271 pub fn new_left(l: L) -> Self {
272 Self::Left(l)
273 }
274
275 pub fn new_right(r: R) -> Self {
276 Self::Right(r)
277 }
278
279 pub fn left(self) -> Option<L> {
281 match self {
282 Either::Left(l) => Some(l),
283 Either::Right(_) => None,
284 }
285 }
286
287 pub fn right(self) -> Option<R> {
289 match self {
290 Either::Right(r) => Some(r),
291 Either::Left(_) => None,
292 }
293 }
294 pub fn unwrap_left(self) -> L {
296 match self {
297 Either::Left(l) => l,
298 Either::Right(_) => panic!("Field is Right, and tried to unwrap as Left"),
299 }
300 }
301
302 pub fn unwrap_right(self) -> R {
304 match self {
305 Either::Right(r) => r,
306 Either::Left(_) => panic!("Field is Left, and tried to unwrap as Right"),
307 }
308 }
309
310}