1use std::error::Error as StdError;
2use std::io;
3use std::process::Output;
4use std::string::FromUtf8Error;
5
6#[derive(Debug)]
7pub enum Error<PE: StdError> {
8 NonUtf8Stdout(FromUtf8Error),
9 ParsingError(PE),
10 ProcessNotSpawned(io::Error),
11 StdoutUnreadable(io::Error),
12 WaitFailed(io::Error),
13 ProcessFailed(Output),
14}
15
16#[derive(Debug, Copy, Clone, Eq, PartialEq)]
18pub enum NeverError {}
19
20impl<PE: StdError> StdError for Error<PE> {
21 fn description(&self) -> &str {
22 match self {
23 Error::NonUtf8Stdout(_) => "subprocess stdout contains non-utf8 characters",
24 Error::ParsingError(_) => "could not parse subprocess output",
25 Error::ProcessNotSpawned(_) => "could not spawn subprocess",
26 Error::StdoutUnreadable(_) => "could not read subprocess stdout",
27 Error::WaitFailed(_) => "subprocess failed",
28 Error::ProcessFailed(_) => "subprocess finished with error",
29 }
30 }
31
32 fn cause(&self) -> Option<&StdError> {
33 match self {
34 Error::NonUtf8Stdout(ref e) => Some(e),
35 Error::ParsingError(ref e) => Some(e),
36 Error::ProcessNotSpawned(ref e) => Some(e),
37 Error::StdoutUnreadable(ref e) => Some(e),
38 Error::WaitFailed(ref e) => Some(e),
39 Error::ProcessFailed(_) => None,
40 }
41 }
42}
43
44impl<PE: StdError> std::fmt::Display for Error<PE> {
45 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
46 write!(f, "{}", self.description())
47 }
48}
49
50impl StdError for NeverError {
51 fn description(&self) -> &str {
52 ""
53 }
54
55 fn cause(&self) -> Option<&StdError> {
56 None
57 }
58}
59
60impl std::fmt::Display for NeverError {
61 fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result {
62 Ok(())
63 }
64}