1use std::error;
2use std::fmt::{self, Display, Formatter};
3use std::io;
4use std::path::PathBuf;
5
6#[derive(Debug, Clone)]
8pub struct CommandFailed {
9 pub dir: PathBuf,
11 pub command: PathBuf,
13 pub args: Vec<String>,
15 pub stderr: Option<String>,
17}
18
19impl Display for CommandFailed {
20 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
21 write!(
22 fmt,
23 "command failed: {}: {}",
24 self.dir.display(),
25 self.command.display()
26 )?;
27 for arg in &self.args {
28 write!(fmt, " {}", arg)?;
29 }
30 if let Some(stderr) = &self.stderr {
31 write!(fmt, ":\n {}", &stderr.trim().replace('\n', "\n "))
32 } else {
33 Ok(())
34 }
35 }
36}
37
38#[derive(Debug)]
40pub enum Error {
41 CommandFailed(CommandFailed),
43 Io(io::Error),
45}
46
47impl Display for Error {
48 fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
49 use Error::*;
50
51 match self {
52 CommandFailed(e) => e.fmt(fmt),
53 Io(e) => e.fmt(fmt),
54 }
55 }
56}
57
58impl error::Error for Error {
59 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
60 use Error::*;
61
62 match self {
63 Io(e) => e.source(),
64 _ => None,
65 }
66 }
67}
68
69impl From<io::Error> for Error {
70 fn from(e: io::Error) -> Self {
71 Error::Io(e)
72 }
73}