19 releases
Uses old Rust 2015
0.2.9 | Jun 8, 2021 |
---|---|
0.2.7 | Sep 17, 2019 |
0.2.6 | Oct 9, 2018 |
0.2.4 | Jul 22, 2018 |
0.1.5 | Jul 29, 2016 |
#474 in Rust patterns
87 downloads per month
Used in 7 crates
21KB
238 lines
command-macros
, crate
Macros for creating std::process::Command
with shell-like syntax.
Created to make using Rust as a scripting language more pleasant.
This crate contains two macros, command!()
– fully-featured,
but requires nightly, and a simpler cmd!()
, built by macro_rules
.
command!
Installation
This macro requires nightly Rust and
enabling a "nightly" feature.
Put the following in your Cargo.toml
.
[dependencies.command-macros]
version = "0.2.9"
features = ["nightly"]
And then add on top of your root module:
#![feature(proc_macro_hygiene)]
extern crate command_macros;
use command_macros::command;
If you're not running the latest nightly, try the following versions:
nightly date | command-macros version |
---|---|
2020-05-20 — | 0.2.9 |
2018-10-06 — 2021-06-05 | 0.2.7 |
2018-10-06 — 2019-08-27 | 0.2.6 |
2018-10-04 — 2018-10-05 | 0.2.5 |
2018-07-17 — 2018-10-03 | 0.2.4 |
2018-05-17 — 2018-07-16 | 0.2.3 |
2018-04-07 — 2018-05-16 | 0.2.2 |
Examples
command!(
ffmpeg -i (file)
-c:v libx264 -preset (preset) [moreargs]
-c:a copy
file:(tmpname)
).status().unwrap();
should be roughly equivalent to running
std::process::Command::new("ffmpeg")
.args(&["-i", &file])
.args(&["-c:v", "libx264", "-preset", &preset])
.args(moreargs)
.args(&["-c:a", "copy"])
.arg(&format!("file:{}", tmpname))
.status()
.unwrap();
As you see, you use (expr)
to create an argument (or a part of it)
from arbitrary Rust expression and [expr]
for multiple arguments.
The &
is added automatically, similarly to how print!
works.
Moreover, command!
will handle file
and tmpname
being OsStr
correctly,
while the manual version would require some modifications.
Additionally, you can use if
, if let
, match
and for
.
This snippet also showcases (( expr ))
feature.
command!(make
if let Some(n) = n_cores { -j ((n + 1)) }
).status().unwrap();
Both macros return Command
by value, so you can store them in a variable for later:
let cmd = command!(mkv --fs);
If you have partially prepared command (Command
or &mut Command
),
you can also pass it to this macro:
let base: Command = prepare();
let cmd = command!({base} install (package));
cmd!
Installation
Put the following in your Cargo.toml
.
[dependencies]
command-macros = "0.2"
And then add on top of your root module:
#[macro_use] extern crate command_macros;
Limitations
This macro is a "lite" version of the command!
.
Differences:
- Worse error messages.
- It is whitespace-insensitive.
- Creating arguments from arbitrary tokens (such as
-c:a
) is not supported (only idents). The workaround is to use Rust string as an expression:("-c:a")
. ((expr))
and(expr)
always evaluate to full argument (no tricks likefile:(filename)
).- Expressions in
if
,match
andfor
have to be surrounded by parens. - No support for
else if
(useelse { if ... }
instead).
Besides, all other features should work.
Examples
Examples from command!
section rewritten to match cmd!
syntax:
command!(
ffmpeg ("-i") (file)
("-c:v") libx264 ("-preset") (preset) [moreargs]
("-c:a") copy
(format!("file:{}", tmpname))
).status().unwrap();
command!(make
if let Some(n) = (n_cores) { ("-j") ((n + 1)) }
).status().unwrap();
Changelog
Dependencies
~70KB