1use std::fmt;
7use std::io::ErrorKind;
8
9#[derive(Debug, Clone, PartialEq)]
11pub struct PosixError {
12 code: i32,
13 message: String,
14}
15
16pub const EPERM: i32 = 1;
18pub const ENOENT: i32 = 2;
20pub const ESRCH: i32 = 3;
22pub const EINTR: i32 = 4;
24pub const EIO: i32 = 5;
26pub const ENXIO: i32 = 6;
28pub const E2BIG: i32 = 7;
30pub const ENOEXEC: i32 = 8;
32pub const EBADF: i32 = 9;
34pub const ECHILD: i32 = 10;
36pub const EDEADLK: i32 = 11;
38pub const ENOMEM: i32 = 12;
40pub const EACCES: i32 = 13;
42pub const EFAULT: i32 = 14;
44pub const ENOTBLK: i32 = 15;
46pub const EBUSY: i32 = 16;
48pub const EEXIST: i32 = 17;
50pub const EXDEV: i32 = 18;
52pub const ENODEV: i32 = 19;
54pub const ENOTDIR: i32 = 20;
56pub const EISDIR: i32 = 21;
58pub const EINVAL: i32 = 22;
60pub const ENFILE: i32 = 23;
62pub const EMFILE: i32 = 24;
64pub const ENOTTY: i32 = 25;
66pub const ETXTBSY: i32 = 26;
68pub const EFBIG: i32 = 27;
70pub const ENOSPC: i32 = 28;
72pub const ESPIPE: i32 = 29;
74pub const EROFS: i32 = 30;
76pub const EMLINK: i32 = 31;
78pub const EPIPE: i32 = 32;
80pub const EDOM: i32 = 33;
82pub const ERANGE: i32 = 34;
84pub const EAGAIN: i32 = 35;
86pub const EWOULDBLOCK: i32 = 35;
88pub const EINPROGRESS: i32 = 36;
90pub const EALREADY: i32 = 37;
92pub const ENOTSOCK: i32 = 38;
94pub const EDESTADDRREQ: i32 = 39;
96pub const EMSGSIZE: i32 = 40;
98pub const EPROTOTYPE: i32 = 41;
100pub const ENOPROTOOPT: i32 = 42;
102pub const EPROTONOSUPPORT: i32 = 43;
104pub const ESOCKTNOSUPPORT: i32 = 44;
106pub const EOPNOTSUPP: i32 = 45;
108pub const ENOTSUP: i32 = 45;
110pub const EPFNOSUPPORT: i32 = 46;
112pub const EAFNOSUPPORT: i32 = 47;
114pub const EADDRINUSE: i32 = 48;
116pub const EADDRNOTAVAIL: i32 = 49;
118pub const ENETDOWN: i32 = 50;
120pub const ENETUNREACH: i32 = 51;
122pub const ENETRESET: i32 = 52;
124pub const ECONNABORTED: i32 = 53;
126pub const ECONNRESET: i32 = 54;
128pub const ENOBUFS: i32 = 55;
130pub const EISCONN: i32 = 56;
132pub const ENOTCONN: i32 = 57;
134pub const ESHUTDOWN: i32 = 58;
136pub const ETOOMANYREFS: i32 = 59;
138pub const ETIMEDOUT: i32 = 60;
140pub const ECONNREFUSED: i32 = 61;
142pub const ELOOP: i32 = 62;
144pub const ENAMETOOLONG: i32 = 63;
146pub const EHOSTDOWN: i32 = 64;
148pub const EHOSTUNREACH: i32 = 65;
150pub const ENOTEMPTY: i32 = 66;
152pub const EPROCLIM: i32 = 67;
154pub const EUSERS: i32 = 68;
156pub const EDQUOT: i32 = 69;
158pub const ESTALE: i32 = 70;
160pub const EREMOTE: i32 = 71;
162pub const EBADRPC: i32 = 72;
164pub const ERPCMISMATCH: i32 = 73;
166pub const EPROGUNAVAIL: i32 = 74;
168pub const EPROGMISMATCH: i32 = 75;
170pub const EPROCUNAVAIL: i32 = 76;
172pub const ENOLCK: i32 = 77;
174pub const ENOSYS: i32 = 78;
176pub const EFTYPE: i32 = 79;
178pub const EAUTH: i32 = 80;
180pub const ENEEDAUTH: i32 = 81;
182pub const EIDRM: i32 = 82;
184pub const ENOMSG: i32 = 83;
186pub const EOVERFLOW: i32 = 84;
188pub const ECANCELED: i32 = 85;
190pub const EILSEQ: i32 = 86;
192pub const ENOATTR: i32 = 87;
194pub const EDOOFUS: i32 = 88;
196pub const EBADMSG: i32 = 89;
198pub const EMULTIHOP: i32 = 90;
200pub const ENOLINK: i32 = 91;
202pub const EPROTO: i32 = 92;
204pub const ENOTCAPABLE: i32 = 93;
206pub const ECAPMODE: i32 = 94;
208pub const ENOTRECOVERABLE: i32 = 95;
210pub const EOWNERDEAD: i32 = 96;
212pub const ELAST: i32 = 96;
214
215pub const ENOTEXEC: i32 = 126;
220
221pub const ENOCMD: i32 = 127;
223
224pub const EINVALEXIT: i32 = 128;
226
227pub const ECTRLC: i32 = 130;
229
230pub const EUTF8: i32 = 166;
234
235impl fmt::Display for PosixError {
236 #[inline]
237 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
238 return write!(f, "{}", self.message);
239 }
240}
241
242impl From<std::io::Error> for PosixError {
243 #[inline]
244 fn from(error: std::io::Error) -> Self {
245 match error.kind() {
246 ErrorKind::NotFound => Self {
247 code: ENOENT,
248 message: error.to_string(),
249 },
250 ErrorKind::PermissionDenied => Self {
251 code: EACCES,
252 message: error.to_string(),
253 },
254 ErrorKind::ConnectionRefused => Self {
255 code: ECONNREFUSED,
256 message: error.to_string(),
257 },
258
259 ErrorKind::ConnectionReset => Self {
260 code: ECONNRESET,
261 message: error.to_string(),
262 },
263 ErrorKind::ConnectionAborted => Self {
264 code: ECONNABORTED,
265 message: error.to_string(),
266 },
267 ErrorKind::NotConnected => Self {
268 code: ENOTCONN,
269 message: error.to_string(),
270 },
271 ErrorKind::AddrInUse => Self {
272 code: EADDRINUSE,
273 message: error.to_string(),
274 },
275 ErrorKind::AddrNotAvailable => Self {
276 code: EADDRNOTAVAIL,
277 message: error.to_string(),
278 },
279 ErrorKind::BrokenPipe => Self {
280 code: EPIPE,
281 message: error.to_string(),
282 },
283 ErrorKind::AlreadyExists => Self {
284 code: EEXIST,
285 message: error.to_string(),
286 },
287 ErrorKind::WouldBlock => Self {
288 code: EWOULDBLOCK,
289 message: error.to_string(),
290 },
291 ErrorKind::InvalidInput => Self {
292 code: EINVAL,
293 message: error.to_string(),
294 },
295 ErrorKind::InvalidData => Self {
296 code: EFTYPE,
297 message: error.to_string(),
298 },
299 ErrorKind::TimedOut => Self {
300 code: ETIMEDOUT,
301 message: error.to_string(),
302 },
303 ErrorKind::WriteZero => Self {
304 code: ENOLINK,
305 message: error.to_string(),
306 },
307 ErrorKind::Interrupted => Self {
308 code: EINTR,
309 message: error.to_string(),
310 },
311 ErrorKind::UnexpectedEof => Self {
312 code: ESHUTDOWN,
313 message: error.to_string(),
314 },
315 _ => Self {
316 code: EPERM,
317 message: error.to_string(),
318 },
319 }
320 }
321}
322
323impl From<std::process::Output> for PosixError {
324 #[inline]
325 fn from(output: std::process::Output) -> Self {
326 let tmp = String::from_utf8_lossy(&output.stderr).to_string();
327 let mut code = output.status.code().unwrap_or(1);
328 if code == 0 {
329 code = 1;
331 }
332 Self::new(code, tmp)
333 }
334}
335
336impl PosixError {
337 #[must_use]
339 #[inline]
340 pub const fn new(code: i32, message: String) -> Self {
341 Self { code, message }
342 }
343
344 #[must_use]
346 #[inline]
347 pub const fn code(&self) -> i32 {
348 self.code
349 }
350
351 #[must_use]
353 #[inline]
354 pub fn message(&self) -> String {
355 self.message.clone()
356 }
357}
358
359#[must_use]
361#[inline]
362pub fn posix_error(code: i32, msg: &str) -> PosixError {
363 PosixError::new(code, msg.to_owned())
364}
365
366#[allow(clippy::needless_pass_by_value)]
368#[deprecated(since = "1.1.0", note = "Please use PosixError::from")]
369#[must_use]
370#[inline]
371pub fn to_posix_error(err: std::io::Error) -> PosixError {
372 PosixError::from(err)
373}
374
375#[must_use]
377#[inline]
378#[deprecated(since = "1.1.0", note = "Please use PosixError::from")]
379pub fn error_from_output(output: std::process::Output) -> PosixError {
380 PosixError::from(output)
381}