isfet/
lib.rs

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// /// Defines what happened
9// #[derive(Default, PartialEq, PartialOrd, Serialize, Deserialize)]
10// pub enum Kind {
11//     /// A necessary thing does not exist
12//     NotExist,
13//     /// A necessary thing was passed, but it couldn't be transformed into the
14//     Malformed,
15//     /// An operation did not complete successfully
16//     Failed,
17//     /// Attempted to do something that it doesn't have authority to do
18//     NotAuthed,
19//     ///
20//     TooBig,
21//     #[default]
22//     Unknown,
23// }
24
25// /// Defines the closest-related data
26// #[derive(Deserialize, Serialize, PartialEq, PartialOrd)]
27// pub enum Object {
28//     File,
29//     Socket,
30//     Directory,
31//     IpAddr,
32
33//     String,
34// }
35
36// #[derive(Deserialize, Serialize, PartialEq, PartialOrd)]
37// pub enum Severity {
38//     /// Something that shouldn't stop computation, but might cause problems
39//     Sus,
40//     Warning,
41//     Error,
42//     Panic,
43// }
44
45#[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		/// Should be lowest level error, if Some
51		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	/// Used for easier backward compability
66	pub fn g<S: AsRef<str>>(description: S) -> Self {
67		Self::new_error(description.as_ref().to_compact_string(), None)
68	}
69
70	/// Returns the description of the lowest error
71	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						// If source is set, it should be set with something
126						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	/// The highest value is resevered for unknown errors
151	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
162/// Defines better semantic meaning for the often use of an empty tuple inside of a Result
163pub type Empty = ();
164
165pub type Res<T> = Result<T, Catastrophe>;
166
167/// Result type with empty tuple
168pub type ResE = Res<Empty>;
169
170/// A better name, in my opinion
171pub type Maybe<T> = Option<T>;
172
173/// A type that actually is optional
174#[cfg_attr(feature = "serde_feature", derive(Deserialize, Serialize))]
175#[derive(Clone, PartialEq, PartialOrd, Default)]
176pub struct Optional<D: Default>(D);
177
178// Newer
179
180#[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
213/// Ignores the parent
214impl 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
228// impl Iterator for &Isfet {
229//     type Item = Self;
230
231//     fn next(&mut self) -> Option<Self::Item> {
232//         if let Some(n) = &self.child {
233// 			Some(n)
234// 		} else {
235// 			None
236// 		}
237//     }
238// }
239
240
241impl<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	/// Returns the left element xor None
280	pub fn left(self) -> Option<L> {
281		match self {
282			Either::Left(l) => Some(l),
283			Either::Right(_) => None,
284		}
285	}
286
287	/// Returns the right element xor None
288	pub fn right(self) -> Option<R> {
289		match self {
290			Either::Right(r) => Some(r),
291			Either::Left(_) => None,
292		}
293	}
294	/// Returns the left element xor panics
295	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	/// Returns the right element xor panics
303	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}