use std::process::Command;
pub trait AsCommand {
fn as_command(&self) -> Command;
}
impl AsCommand for [&str] {
fn as_command(&self) -> Command {
let mut command = Command::new(self[0]);
command.args(&self[1..]);
command
}
}
impl AsCommand for [String] {
fn as_command(&self) -> Command {
let parts: Vec<&str> = self.iter().map(|s| s.as_str()).collect();
parts.as_command()
}
}
impl AsCommand for &[&str] {
fn as_command(&self) -> Command {
self[..].as_command()
}
}
impl AsCommand for &[String] {
fn as_command(&self) -> Command {
self[..].as_command()
}
}
impl<const N: usize> AsCommand for [&str; N] {
fn as_command(&self) -> Command {
self.as_slice().as_command()
}
}
impl<const N: usize> AsCommand for [String; N] {
fn as_command(&self) -> Command {
self.as_slice().as_command()
}
}
impl AsCommand for Vec<&str> {
fn as_command(&self) -> Command {
self.as_slice().as_command()
}
}
impl AsCommand for Vec<String> {
fn as_command(&self) -> Command {
self.as_slice().as_command()
}
}
impl AsCommand for str {
fn as_command(&self) -> Command {
let parts = shell_words::split(self).expect("Failed to parse command string");
parts.as_command()
}
}
impl AsCommand for &str {
fn as_command(&self) -> Command {
let parts = shell_words::split(self).expect("Failed to parse command string");
parts.as_command()
}
}
impl AsCommand for String {
fn as_command(&self) -> Command {
self.as_str().as_command()
}
}
#[cfg(test)]
mod tests {
use super::*;
fn check_command(cmd: &Command, expected_program: &str, expected_args: &[&str]) {
assert_eq!(cmd.get_program().to_str().unwrap(), expected_program);
let args: Vec<&str> = cmd.get_args().map(|a| a.to_str().unwrap()).collect();
assert_eq!(args, expected_args);
}
#[test]
fn test_as_command_from_str_slice_reference() {
let cmd: &[&str] = &["echo", "Hello, world!"];
let cmd = cmd.as_command();
check_command(&cmd, "echo", &["Hello, world!"]);
}
#[test]
fn test_as_command_from_string_slice_reference() {
let cmd: &[&str] = &["echo", "Hello, world!"];
let cmd = cmd.as_command();
check_command(&cmd, "echo", &["Hello, world!"]);
}
#[test]
fn test_as_command_from_str_array() {
let cmd: [&str; 2] = ["echo", "Hello, world!"];
let cmd = cmd.as_command();
check_command(&cmd, "echo", &["Hello, world!"]);
}
#[test]
fn test_as_command_from_string_array() {
let cmd: [String; 2] = [String::from("echo"), String::from("Hello, world!")];
let cmd = cmd.as_command();
check_command(&cmd, "echo", &["Hello, world!"]);
}
#[test]
fn test_as_command_from_str_vector() {
let cmd: Vec<&str> = vec!["echo", "Hello, world!"];
let cmd = cmd.as_command();
check_command(&cmd, "echo", &["Hello, world!"]);
}
#[test]
fn test_as_command_from_string_vector() {
let cmd: Vec<String> = vec![String::from("echo"), String::from("Hello, world!")];
let cmd = cmd.as_command();
check_command(&cmd, "echo", &["Hello, world!"]);
}
#[test]
fn test_as_command_from_str() {
let cmd: &str = "echo \"Hello, world!\"";
let cmd = cmd.as_command();
check_command(&cmd, "echo", &["Hello, world!"]);
}
#[test]
fn test_as_command_from_string() {
let cmd: String = "echo \"Hello, world!\"".into();
let cmd = cmd.as_command();
check_command(&cmd, "echo", &["Hello, world!"]);
}
}