1#[repr(transparent)]
2#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3pub struct CommandFailedOutput(pub Vec<u8>);
4impl std::fmt::Display for CommandFailedOutput {
5 #[inline]
6 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7 write!(f, "{}", String::from_utf8_lossy(&self.0))
8 }
9}
10impl std::fmt::Debug for CommandFailedOutput {
11 #[inline]
12 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13 std::fmt::Display::fmt(self, f)
14 }
15}
16impl From<CommandFailedOutput> for Vec<u8> {
17 #[inline(always)]
18 fn from(out: CommandFailedOutput) -> Self {
19 out.0
20 }
21}
22
23#[derive(Debug)]
24pub enum Error {
26 SystemHTTPClientNotFound,
28
29 IoError(std::io::Error),
33
34 InvalidUrl(url::ParseError),
36
37 InvalidUrlScheme,
39
40 CommandFailed {
42 status: std::process::ExitStatus,
44
45 stdout: CommandFailedOutput,
47
48 stderr: CommandFailedOutput,
50 },
51}
52impl std::fmt::Display for Error {
53 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54 match self {
55 Error::SystemHTTPClientNotFound => {
56 write!(f, "This system does not have an HTTP client installed")
57 }
58 Error::IoError(e) => write!(f, "I/O error: {}", e),
59 Error::InvalidUrl(e) => write!(f, "Invalid URL: {}", e),
60 Error::InvalidUrlScheme => write!(f, "URL must have http or https scheme"),
61 Error::CommandFailed { status, .. } => write!(f, "Process exited with code {status:?}"),
62 }
63 }
64}
65impl std::error::Error for Error {}
66impl From<url::ParseError> for Error {
67 fn from(err: url::ParseError) -> Self {
68 Self::InvalidUrl(err)
69 }
70}
71impl From<std::io::Error> for Error {
72 fn from(err: std::io::Error) -> Self {
73 Self::IoError(err)
74 }
75}