1use lliw::Fg::Red;
2use lliw::Reset;
3use std::fmt::{Display, Formatter};
4use std::num::ParseIntError;
5
6#[macro_export]
8macro_rules! pass {
9 () => {
10 Ok(())
11 };
12 ($item:expr) => {{
13 Ok($item)
14 }};
15}
16
17#[macro_export]
19macro_rules! throw {
20 ($kind:expr, $fmt:literal) => ({
21 return $crate::error::_throw($kind, std::format!($fmt))
22 });
23 ($kind:expr, $fmt:literal, $($arg:tt)*) => ({
24 return $crate::error::_throw($kind, std::format!($fmt, $($arg)*))
25 })
26}
27
28#[doc(hidden)]
29pub fn _throw<T>(kind: Kind, inner: String) -> Result<T, Error> {
30 Err(Error::new(kind, inner))
31}
32
33#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
35pub struct Error {
36 inner: String,
37 kind: Kind,
39}
40
41impl Error {
42 #[must_use]
43 pub fn new(kind: Kind, inner: String) -> Error {
45 Error { inner, kind }
46 }
47
48 #[must_use]
49 pub fn kind(&self) -> Kind {
51 self.kind
52 }
53}
54
55impl Display for Error {
56 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
57 write!(f, "{}{}: {}{}", Red, self.kind, Reset, self.inner)
58 }
59}
60
61impl From<ParseIntError> for Error {
62 fn from(pie: ParseIntError) -> Self {
63 Error::new(Kind::VersionParse, pie.to_string())
64 }
65}
66
67impl From<toml::de::Error> for Error {
68 fn from(te: toml::de::Error) -> Self {
69 Error::new(Kind::ConfigParse, te.to_string())
70 }
71}
72
73impl From<jargon_args::Error> for Error {
74 fn from(jae: jargon_args::Error) -> Self {
75 match jae {
76 jargon_args::Error::MissingArg(key) => {
77 Error::new(Kind::ArgumentMissing, key.to_string())
78 }
79 jargon_args::Error::Other(s) => Error::new(Kind::JargonInternal, s),
80 }
81 }
82}
83
84impl std::error::Error for Error {}
85
86#[repr(i32)]
88#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
89pub enum Kind {
90 Internal = 1,
92 Environment,
94 ConfigOpen,
96 ConfigRead,
98 ConfigParse,
100 ProtonDir,
102 ProtonSpawn,
104 ProtonWait,
106 ProtonMissing,
108 ProgramMissing,
110 IndexReadDir,
112 VersionParse,
114 ProtonExit,
116 ArgumentMissing,
118 JargonInternal,
120 IndexCache,
122 ParseRuntimeOpt,
124 RuntimeMissing,
126}
127
128impl Display for Kind {
129 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
130 write!(
131 f,
132 "{}",
133 match self {
134 Kind::Internal => "internal error",
135 Kind::Environment => "failed to read environment",
136 Kind::ConfigOpen => "failed to open config",
137 Kind::ConfigRead => "failed to read config",
138 Kind::ConfigParse => "failed to parse config",
139 Kind::ProtonDir => "failed to create Proton directory",
140 Kind::ProtonSpawn => "failed to spawn Proton",
141 Kind::ProtonWait => "failed to wait for Proton child",
142 Kind::IndexReadDir => "failed to Index",
143 Kind::VersionParse => "failed to parse version",
144 Kind::ProtonMissing => "cannot find Proton",
145 Kind::ProgramMissing => "cannot find program",
146 Kind::ProtonExit => "proton exited with",
147 Kind::ArgumentMissing => "missing command line argument",
148 Kind::JargonInternal => "jargon args internal error",
149 Kind::IndexCache => "failed read/write to cache",
150 Kind::ParseRuntimeOpt => "failed parsing runtime option",
151 Kind::RuntimeMissing => "failed to find Runtime",
152 }
153 )
154 }
155}