cmd!() { /* proc-macro */ }Expand description
Generates a command expression by combining static strings, conditional logic, loops, pattern matching, and closures to dynamically build and format command-line arguments.
The cmd! 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 command = cmd!("echo", "test");
assert_eq!(format!("{command:?}"), r#""echo" "test""#.to_string());§Current Directory
let command = cmd!(
cd "~/";
"echo",
"test",
);
assert_eq!(format!("{command:?}"), r#"cd "~/" && "echo" "test""#);§Environment Vars
const NEW_VAR: &str = "NEW_VAR";
let command = cmd!(
env {
"TEST": "test",
NEW_VAR: "new_var"
};
"echo",
"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 command = cmd!(
env {
"TEST":? "test",
NEW_VAR: "new_var"
};
"echo",
"test",
);
assert_eq!(format!("{command:?}"), r#"NEW_VAR="new_var" "echo" "test""#);§Current Directory and Environment Variable Order
let command = cmd!(
cd "~/";
env {
"TEST": "test",
};
"echo",
"test",
);
assert_eq!(
format!("{command:?}"),
r#"cd "~/" && TEST="test" "echo" "test""#
);
§Conditional Arguments
let include_arg = true;
let command = cmd!("echo", "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 command = cmd!(
"echo",
"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 command = cmd!("echo", 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 command = cmd!(
"echo",
"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 command = cmd!(
"echo",
"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 command = cmd!("echo", || numbers.into_iter().map(|n| format!("{}", n * multiplier)));
assert_eq!(format!("{command:?}"), r#""echo" "2" "4" "6""#.to_string());