simple_cmd/
errors.rs

1use std::fmt::{Debug, Display, Formatter};
2use std::process::{ExitStatus, Output};
3
4use thiserror::Error;
5
6use crate::Vec8ToString;
7
8#[derive(Error, Clone, PartialEq, Eq)]
9pub struct CmdError {
10	pub status: Option<ExitStatus>,
11	pub stdout: Vec<u8>,
12	pub stderr: Vec<u8>,
13}
14
15impl Debug for CmdError {
16	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
17		f.debug_struct("CmdError")
18			.field("status", &self.status)
19			.field("stdout", &self.stdout.as_str())
20			.field("stderr", &self.stderr.as_str())
21			.finish()
22	}
23}
24
25impl From<Output> for CmdError {
26	fn from(value: Output) -> Self {
27		CmdError::from_err(value.status, value.stdout, value.stderr)
28	}
29}
30
31impl From<Output> for crate::Error {
32	fn from(value: Output) -> Self {
33		crate::Error::CommandError(value.into())
34	}
35}
36
37impl CmdError {
38	pub fn from_err(status: ExitStatus, stdout: Vec<u8>, stderr: Vec<u8>) -> Self {
39		CmdError {
40			status: Some(status),
41			stdout,
42			stderr,
43		}
44	}
45
46	pub fn from_status(status: ExitStatus) -> Self {
47		CmdError {
48			status: Some(status),
49			stdout: vec![],
50			stderr: vec![],
51		}
52	}
53
54	pub fn from_str(msg: &str) -> Self {
55		CmdError {
56			status: None,
57			stdout: vec![],
58			stderr: msg.to_owned().into_bytes(),
59		}
60	}
61
62	pub fn exit_code(&self) -> Option<i32> {
63		match self.status {
64			Some(s) => s.code(),
65			None => None,
66		}
67	}
68}
69
70impl Display for CmdError {
71	fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
72		if let Some(status) = self.status {
73			if let Some(code) = status.code() {
74				let _ = write!(f, "exit code: {}", code);
75			} else {
76				let _ = write!(f, "exit status: {}", self.status.unwrap_or(ExitStatus::default()));
77			}
78		} else {
79			let _ = write!(f, "exit status: {}", self.status.unwrap_or(ExitStatus::default()));
80		}
81
82		if !self.stderr.is_empty() {
83			write!(f, ", stderr: {}", self.stderr.as_str().unwrap_or(""))
84		} else {
85			write!(f, ", stdout: {}", self.stdout.as_str().unwrap_or(""))
86		}
87	}
88}