use std::ffi::OsStr;
use std::process::Command;
use std::str;
pub struct Executor {}
impl Executor {
pub fn exec<T: AsRef<OsStr>>(
command: T,
composer: impl Fn(&mut Command) -> &mut Command,
) -> String {
let output = composer(&mut Executor::spawn(command))
.output()
.expect("command failed to execute");
if output.status.success() {
return Executor::unwrap(&output.stdout);
}
Executor::unwrap(&output.stderr)
}
pub fn exec_with_errors<T: AsRef<OsStr>>(
command: T,
composer: impl Fn(&mut Command) -> &mut Command,
) -> Option<String> {
let output = composer(&mut Executor::spawn(command))
.output()
.expect("command failed to execute");
if output.status.success() {
return None;
}
Some(Executor::unwrap(&output.stderr))
}
pub fn exec_with_stdout<T: AsRef<OsStr>>(
command: T,
composer: impl Fn(&mut Command) -> &mut Command,
) -> Option<String> {
let output = composer(&mut Executor::spawn(command))
.output()
.expect("command failed to execute");
if output.status.success() {
return Some(Executor::unwrap(&output.stdout));
}
None
}
pub fn with_stdio<T: AsRef<OsStr>>(
command: T,
composer: impl Fn(&mut Command) -> &mut Command,
) -> bool {
let child = composer(&mut Executor::spawn(command))
.spawn()
.expect("Failed to execute");
let output = child
.wait_with_output()
.expect("failed to wait on child process");
output.status.success()
}
pub fn spawn<T: AsRef<OsStr>>(program: T) -> Command {
let mut command = Executor::platform_command();
command.arg(program);
command
}
fn platform_command() -> Command {
if cfg!(target_os = "windows") {
return Executor::windows_command();
}
Executor::unix_command()
}
fn windows_command() -> Command {
let mut child_process = Command::new("cmd");
child_process.arg("/C");
child_process
}
fn unix_command() -> Command {
let mut child_process = Command::new("sh");
child_process.arg("-c");
child_process
}
fn unwrap(io: &[u8]) -> String {
str::from_utf8(io)
.expect("Invalid output")
.trim()
.to_string()
}
}