cmd_mut!() { /* proc-macro */ }Expand description
Mutates a command by combining static strings, conditional logic, loops, pattern matching, and closures to dynamically build and format command-line arguments.
Arguments and environment variables are appended to the existing Command. The working
directory is replaced if set with this macro.
The cmd_mut! macro supports flexible syntax constructs such as:
- Static arguments: Basic string arguments.
- Conditional inclusion: Using
iforif letto conditionally include arguments. - Iterative inclusion: Using
forloops to include multiple arguments from collections. - Pattern matching: Using
matchexpressions for dynamic argument selection. - Closures: Dynamically generating arguments at runtime.
§Examples
§Basic Usage
let mut command = cmd!("echo");
cmd_mut!(&mut command, "test");
assert_eq!(format!("{command:?}"), r#""echo" "test""#.to_string());§Current Directory
let mut command = cmd!("echo");
cmd_mut!(
cd "~/";
&mut command,
"test",
);
assert_eq!(format!("{command:?}"), r#"cd "~/" && "echo" "test""#);§Environment Vars
const NEW_VAR: &str = "NEW_VAR";
let mut command = cmd!("echo");
cmd_mut!(
env {
"TEST": "test",
NEW_VAR: "new_var"
};
&mut command,
"test",
);
assert_eq!(format!("{command:?}"), r#"NEW_VAR="new_var" TEST="test" "echo" "test""#);§Conditional
You can have a default value set for an environment variable.
const NEW_VAR: &str = "NEW_VAR";
std::env::set_var("TEST", "realvalue");
let mut command = cmd!("echo");
cmd_mut!(
env {
"TEST":? "test",
NEW_VAR: "new_var"
};
&mut command,
"test",
);
assert_eq!(format!("{command:?}"), r#"NEW_VAR="new_var" "echo" "test""#);§Current Directory and Environment Variable Order
let mut command = cmd!("echo");
cmd_mut!(
cd "~/";
env {
"TEST": "test",
};
&mut command,
"test",
);
assert_eq!(
format!("{command:?}"),
r#"cd "~/" && TEST="test" "echo" "test""#
);
§Conditional Arguments
let include_arg = true;
let mut command = cmd!("echo");
cmd_mut!(&mut command, "test", if include_arg => "optional_arg");
assert_eq!(format!("{command:?}"), r#""echo" "test" "optional_arg""#.to_string());§Conditional Pattern Matching
let single_option = Some("single");
let multi_option: Option<&str> = None;
let mut command = cmd!("echo");
cmd_mut!(
&mut command,
"test",
if let Some(arg) = single_option => arg,
if let Some(arg) = multi_option => [
"multi",
arg,
],
);
assert_eq!(format!("{command:?}"), r#""echo" "test" "single""#.to_string());§Iterative Argument Inclusion
let args = &["arg1", "arg2"];
let mut command = cmd!("echo");
cmd_mut!(&mut command, for args);
assert_eq!(format!("{command:?}"), r#""echo" "arg1" "arg2""#.to_string());§Iteration with for in
let single_iter = &["arg1", "arg2"];
let multi_iter = &["multi1", "multi2"];
let mut command = cmd!("echo");
cmd_mut!(
&mut command,
"test",
for arg in single_iter => arg,
for arg in multi_iter => [
"multi",
arg,
],
);
assert_eq!(format!("{command:?}"), r#""echo" "test" "arg1" "arg2" "multi" "multi1" "multi" "multi2""#.to_string());§Match Statements
enum TestArgs {
Arg1,
Arg2,
Arg3,
}
let match_arg = TestArgs::Arg2;
let mut command = cmd!("echo");
cmd_mut!(
&mut command,
"test",
match match_arg {
TestArgs::Arg1 => "arg1",
TestArgs::Arg2 => ["arg1", "arg2"],
TestArgs::Arg3 => ["arg1", "arg2", "arg3"],
}
);
assert_eq!(format!("{command:?}"), r#""echo" "test" "arg1" "arg2""#.to_string());§Dynamic Closures
let numbers = vec![1, 2, 3];
let multiplier = 2;
let mut command = cmd!("echo");
cmd_mut!(&mut command, || numbers.into_iter().map(|n| format!("{}", n * multiplier)));
assert_eq!(format!("{command:?}"), r#""echo" "2" "4" "6""#.to_string());