1use std::{fmt, io};
2
3#[derive(Debug)]
4pub enum ArgsError {
5 #[cfg(feature = "clap")]
6 Clap(clap::Error),
7 Msg(String)
8}
9
10#[derive(Debug, Default)]
12pub struct AppErrors<ApEr> {
13 pub init: Option<ApEr>,
14 pub run: Option<ApEr>,
15 pub shutdown: Option<ApEr>
16}
17
18impl<ApEr> AppErrors<ApEr> {
19 pub const fn init_failed(&self) -> bool {
20 self.init.is_some()
21 }
22
23 pub const fn run_failed(&self) -> bool {
24 self.run.is_some()
25 }
26
27 pub const fn shutdown_failed(&self) -> bool {
28 self.shutdown.is_some()
29 }
30}
31
32
33#[derive(Debug)]
35#[allow(clippy::module_name_repetitions)]
36pub enum CbErr<ApEr> {
37 Lib(Error),
39
40 App(ApEr),
45
46 #[cfg(feature = "rt")]
49 #[cfg_attr(docsrs, doc(cfg(feature = "rt")))]
50 SrvApp(AppErrors<ApEr>)
51}
52
53impl<ApEr: fmt::Debug> std::error::Error for CbErr<ApEr> {}
54
55impl<ApEr> fmt::Display for CbErr<ApEr> {
56 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57 match self {
58 Self::Lib(e) => e.fmt(f),
59 Self::App(_ae) => {
60 write!(f, "Application-defined error")
62 }
63 #[cfg(feature = "rt")]
64 Self::SrvApp(e) => {
65 let mut v = vec![];
66 if e.init.is_some() {
67 v.push("init");
68 }
69 if e.run.is_some() {
70 v.push("run");
71 }
72 if e.shutdown.is_some() {
73 v.push("shutdown");
74 }
75 write!(f, "Server application failed [{}]", v.join(","))
76 }
77 }
78 }
79}
80
81impl<ApEr> CbErr<ApEr> {
82 pub fn unwrap_apperr(self) -> ApEr {
87 let Self::App(ae) = self else {
88 panic!("Not CbErr::App()");
89 };
90 ae
91 }
92}
93
94impl<ApEr> From<Error> for CbErr<ApEr> {
95 fn from(err: Error) -> Self {
96 Self::Lib(err)
97 }
98}
99
100#[cfg(feature = "rocket")]
101impl<ApEr> From<rocket::Error> for CbErr<ApEr> {
102 fn from(err: rocket::Error) -> Self {
103 Self::Lib(Error::Rocket(err.to_string()))
104 }
105}
106
107impl<ApEr> From<std::io::Error> for CbErr<ApEr> {
108 fn from(err: std::io::Error) -> Self {
109 Self::Lib(Error::IO(err.to_string()))
110 }
111}
112
113
114#[derive(Debug)]
116pub enum Error {
117 ArgP(ArgsError),
118 BadFormat(String),
119 Internal(String),
120 IO(String),
121
122 LumberJack(String),
129
130 Missing(String),
132
133 #[cfg(feature = "rocket")]
135 #[cfg_attr(docsrs, doc(cfg(feature = "rocket")))]
136 Rocket(String),
137 SubSystem(String),
138
139 Unsupported
140}
141
142
143#[allow(clippy::needless_pass_by_value)]
144impl Error {
145 pub fn bad_format(s: impl ToString) -> Self {
146 Self::BadFormat(s.to_string())
147 }
148
149 pub fn internal(s: impl ToString) -> Self {
150 Self::Internal(s.to_string())
151 }
152
153 pub fn io(s: impl ToString) -> Self {
154 Self::IO(s.to_string())
155 }
156
157 pub fn lumberjack(s: impl ToString) -> Self {
158 Self::LumberJack(s.to_string())
159 }
160
161 pub fn missing(s: impl ToString) -> Self {
162 Self::Missing(s.to_string())
163 }
164}
165
166
167impl std::error::Error for Error {}
168
169impl fmt::Display for Error {
170 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
171 match self {
172 Self::ArgP(s) => {
173 write!(f, "Argument parser; {s:?}")
175 }
176 Self::BadFormat(s) => write!(f, "Bad format error; {s}"),
177 Self::Internal(s) => write!(f, "Internal error; {s}"),
178 Self::IO(s) => write!(f, "I/O error; {s}"),
179 Self::LumberJack(s) => write!(f, "LumberJack error; {s}"),
180 Self::Missing(s) => write!(f, "Missing data; {s}"),
181 #[cfg(feature = "rocket")]
182 Self::Rocket(s) => write!(f, "Rocket error; {s}"),
183 Self::SubSystem(s) => write!(f, "Service subsystem error; {s}"),
184 Self::Unsupported => {
185 write!(f, "Operation is unsupported [on this platform]")
186 }
187 }
188 }
189}
190
191#[cfg(windows)]
202impl From<eventlog::InitError> for Error {
203 fn from(err: eventlog::InitError) -> Self {
205 Self::LumberJack(err.to_string())
206 }
207}
208
209#[cfg(windows)]
210impl From<eventlog::Error> for Error {
211 fn from(err: eventlog::Error) -> Self {
213 Self::LumberJack(err.to_string())
214 }
215}
216
217impl From<io::Error> for Error {
218 fn from(err: io::Error) -> Self {
219 Self::IO(err.to_string())
220 }
221}
222
223#[cfg(windows)]
224impl From<registry::key::Error> for Error {
225 fn from(err: registry::key::Error) -> Self {
226 Self::SubSystem(err.to_string())
227 }
228}
229
230#[cfg(feature = "rocket")]
231impl From<rocket::Error> for Error {
232 fn from(err: rocket::Error) -> Self {
233 Self::Rocket(err.to_string())
234 }
235}
236
237#[cfg(feature = "installer")]
238impl From<sidoc::Error> for Error {
239 fn from(err: sidoc::Error) -> Self {
240 Self::Internal(err.to_string())
241 }
242}
243
244#[cfg(windows)]
245impl From<windows_service::Error> for Error {
246 fn from(err: windows_service::Error) -> Self {
247 Self::SubSystem(err.to_string())
248 }
249}
250
251#[cfg(windows)]
252impl<ApEr> From<windows_service::Error> for CbErr<ApEr> {
253 fn from(err: windows_service::Error) -> Self {
254 Self::Lib(Error::SubSystem(err.to_string()))
255 }
256}
257
258
259