devx_cmd/
error.rs

1use crate::{Child, Cmd};
2use std::fmt;
3
4/// Shortcut for `Result<T, devx_cmd::Error>`
5pub type Result<T, E = Error> = std::result::Result<T, E>;
6
7/// Opaque error which happened during command execution.
8#[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}