std_ext/
command_ext.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
pub trait CommandExt {
    fn run(&mut self) -> std::io::Result<()>;

}

pub trait OutputExt {
    fn stdout(&self) -> &str;
    fn stderr(&self) -> &str;
}

impl CommandExt for std::process::Command {
    fn run(&mut self) -> std::io::Result<()> {
        let status = self.status()?;
        if !status.success() {
            return Err(std::io::Error::new(
                std::io::ErrorKind::Other,
                format!("Command failed with status: {}", status),
            ));
        }
        Ok(())
    }
}

impl OutputExt for std::process::Output {
    fn stdout(&self) -> &str {
        std::str::from_utf8(&self.stdout).expect("Failed to convert stdout to str")
    }

    fn stderr(&self) -> &str {
        std::str::from_utf8(&self.stderr).expect("Failed to convert stderr to str")
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_output() -> std::io::Result<()> {
        let s = std::process::Command::new("echo")
            .arg("hello")
            .output()?
            .stdout();
        assert_eq!(s, "hello\n");
        Ok(())
    }

    #[test]
    fn test_run() -> std::io::Result<()> {
        std::process::Command::new("echo")
            .arg("hello")
            .run()?;
        Ok(())
    }
}