urma-node 0.7.0

Optional URMA archive node: Litecoin follower, record archive, libp2p overlay and loopback service
Documentation
use crate::install::Error;
use std::process::{Command, Stdio};

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Outcome {
    pub success: bool,
    pub stdout: String,
    pub stderr: String,
}

pub trait Runner {
    fn run(&mut self, program: &str, args: &[&str]) -> Result<Outcome, Error>;

    fn require(&mut self, program: &str, args: &[&str]) -> Result<Outcome, Error> {
        let outcome = self.run(program, args)?;
        match outcome.success {
            true => Ok(outcome),
            false => Err(failure(program, args, outcome.stderr.trim().to_owned())),
        }
    }
}

pub struct Commands;

fn failure(program: &str, args: &[&str], detail: String) -> Error {
    Error::Command {
        program: program.to_owned(),
        args: args.iter().map(|arg| (*arg).to_owned()).collect(),
        detail,
    }
}

fn text(program: &str, args: &[&str], bytes: Vec<u8>) -> Result<String, Error> {
    String::from_utf8(bytes).map_err(|error| failure(program, args, error.to_string()))
}

impl Runner for Commands {
    fn run(&mut self, program: &str, args: &[&str]) -> Result<Outcome, Error> {
        let output = Command::new(program)
            .args(args)
            .stdin(Stdio::null())
            .output()
            .map_err(|error| failure(program, args, error.to_string()))?;
        Ok(Outcome {
            success: output.status.success(),
            stdout: text(program, args, output.stdout)?,
            stderr: text(program, args, output.stderr)?,
        })
    }
}