asimov_runner/
executor_error.rs1use crate::SysexitsError;
4use core::fmt;
5use std::{ffi::OsString, io::Cursor};
6
7pub type ExecutorResult = std::result::Result<Cursor<Vec<u8>>, ExecutorError>;
8
9#[derive(Debug)]
10pub enum ExecutorError {
11 MissingProgram(OsString),
12 SpawnFailure(std::io::Error),
13 Failure(SysexitsError, Option<String>),
14 UnexpectedFailure(Option<i32>, Option<String>),
15 UnexpectedOther(std::io::Error),
16}
17
18impl core::error::Error for ExecutorError {}
19
20impl fmt::Display for ExecutorError {
21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22 match self {
23 Self::MissingProgram(program) => {
24 write!(f, "Missing program: {}", program.to_string_lossy())
25 },
26 Self::SpawnFailure(err) => write!(f, "Failed to spawn process: {}", err),
27 Self::Failure(error, stderr) => {
28 write!(
29 f,
30 "Command failed with exit code {}",
31 error.code().unwrap_or(-1),
32 )?;
33 if let Some(stderr) = stderr {
34 write!(f, "\n{}", stderr)?;
35 }
36 Ok(())
37 },
38 Self::UnexpectedFailure(code, stderr) => {
39 write!(
40 f,
41 "Command failed with unexpected exit code: {}",
42 code.unwrap_or(-1)
43 )?;
44 if let Some(stderr) = stderr {
45 write!(f, "\n{}", stderr)?;
46 }
47 Ok(())
48 },
49 Self::UnexpectedOther(err) => write!(f, "Unexpected error: {}", err),
50 }
51 }
52}
53
54#[cfg(feature = "std")]
55impl From<std::io::Error> for ExecutorError {
56 fn from(error: std::io::Error) -> Self {
57 Self::UnexpectedOther(error)
58 }
59}
60
61#[cfg(feature = "std")]
62impl From<std::process::ExitStatus> for ExecutorError {
63 fn from(status: std::process::ExitStatus) -> Self {
64 match SysexitsError::try_from(status) {
65 Ok(error) => Self::Failure(error, None),
66 Err(code) => Self::UnexpectedFailure(code, None),
67 }
68 }
69}
70
71#[cfg(feature = "std")]
72impl From<std::process::Output> for ExecutorError {
73 fn from(output: std::process::Output) -> Self {
74 let stderr = String::from_utf8(output.stderr).ok();
75 match SysexitsError::try_from(output.status) {
76 Ok(error) => Self::Failure(error, stderr),
77 Err(code) => Self::UnexpectedFailure(code, stderr),
78 }
79 }
80}