1use crate::{Child, Cmd};
2use std::fmt;
3
4pub type Result<T, E = Error> = std::result::Result<T, E>;
6
7#[derive(Debug)]
9pub struct Error(String);
10
11impl std::error::Error for Error {}
12
13pub(crate) trait Context<T> {
14 fn cmd_context(self, cmd: &Cmd) -> Result<T>;
15 fn proc_context(self, proc: &Child) -> Result<T>;
16}
17impl<T, E: fmt::Display> Context<T> for Result<T, E> {
18 fn cmd_context(self, cmd: &Cmd) -> Result<T> {
19 self.map_err(|err| Error::cmd(cmd, &err))
20 }
21 fn proc_context(self, proc: &Child) -> Result<T> {
22 self.map_err(|err| Error::proc(proc, &err))
23 }
24}
25
26impl Error {
27 fn new(msg: String, log_level: Option<log::Level>) -> Self {
28 let me = Self(msg);
29 if let Some(level) = log_level {
30 log::log!(level, "[ERROR] {}", me.0);
31 }
32 me
33 }
34
35 fn cmd(cmd: &Cmd, message: &dyn fmt::Display) -> Self {
36 let msg = format!("{}\nCommand: {}", message, cmd);
37 Self::new(msg, cmd.0.log_err)
38 }
39 pub(crate) fn proc(proc: &Child, message: &dyn fmt::Display) -> Self {
40 let msg = format!("{}\nProcess: {}", message, proc);
41 Self::new(msg, proc.cmd.0.log_err)
42 }
43}
44
45impl fmt::Display for Error {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 f.write_str(&self.0)
48 }
49}