urma_node/install/
runner.rs1use crate::install::Error;
2use std::process::{Command, Stdio};
3
4#[derive(Clone, Debug, PartialEq, Eq)]
5pub struct Outcome {
6 pub success: bool,
7 pub stdout: String,
8 pub stderr: String,
9}
10
11pub trait Runner {
12 fn run(&mut self, program: &str, args: &[&str]) -> Result<Outcome, Error>;
13
14 fn require(&mut self, program: &str, args: &[&str]) -> Result<Outcome, Error> {
15 let outcome = self.run(program, args)?;
16 match outcome.success {
17 true => Ok(outcome),
18 false => Err(failure(program, args, outcome.stderr.trim().to_owned())),
19 }
20 }
21}
22
23pub struct Commands;
24
25fn failure(program: &str, args: &[&str], detail: String) -> Error {
26 Error::Command {
27 program: program.to_owned(),
28 args: args.iter().map(|arg| (*arg).to_owned()).collect(),
29 detail,
30 }
31}
32
33fn text(program: &str, args: &[&str], bytes: Vec<u8>) -> Result<String, Error> {
34 String::from_utf8(bytes).map_err(|error| failure(program, args, error.to_string()))
35}
36
37impl Runner for Commands {
38 fn run(&mut self, program: &str, args: &[&str]) -> Result<Outcome, Error> {
39 let output = Command::new(program)
40 .args(args)
41 .stdin(Stdio::null())
42 .output()
43 .map_err(|error| failure(program, args, error.to_string()))?;
44 Ok(Outcome {
45 success: output.status.success(),
46 stdout: text(program, args, output.stdout)?,
47 stderr: text(program, args, output.stderr)?,
48 })
49 }
50}