rhai-process
Overview
rhai-process is a Rust crate that lets Rhai scripts execute external processes in an OS-agnostic and safe way. It focuses on structured array-based commands so CLI/DSL apps can expose a consistent execution interface.
Rhai Script
let result = cmd(["ls"])
.pipe(cmd(["grep", "Cargo.toml"]))
.build()
.run();
if result.success {
print(result.stdout);
}
Rust Source
use rhai::packages::Package;
use rhai::{Engine, EvalAltResult};
use rhai_process::{Config, ProcessPackage};
fn main() -> Result<(), Box<EvalAltResult>> {
let mut engine = Engine::new();
let package = ProcessPackage::new(Config::default());
package.register_into_engine(&mut engine);
let contents = engine.eval::<String>(r#"
let result = cmd(["ls"])
.pipe(cmd(["grep", "Cargo.toml"]))
.build()
.run();
if result.success {
result.stdout
}
"#)?;
println!("{}", contents);
Ok(())
}
Config
Host applications use Config to control what Rhai scripts may execute.
| Option |
Description |
allow_commands([...]) / deny_commands([...]) |
Whitelist or blacklist executable names (mutually exclusive). When unspecified, all commands are allowed. |
allow_env_vars([...]) / deny_env_vars([...]) |
Restrict which environment-variable keys scripts may override (mutually exclusive). Unset means all keys are allowed. |
default_timeout_ms(ms) |
Default timeout in milliseconds. Zero or negative values are rejected. Call Executor::timeout(ms) to override per pipeline. |
Every CommandBuilder consults this policy before launching. Violations raise an immediate Rhai error and the external process is never started.
CommandBuilder
let run = cmd(["cargo", "build"])
.env(#{ "RUSTFLAGS": "-Dwarnings" })
.build()
.cwd(repo_dir);
| Method |
Description |
cmd([cmd, opt, ...]) |
Create a builder by passing the program name and arguments as an array. |
env(map) / env_var(key, value) |
Inject environment variables (collectively or individually). Keys must be allowed by Config. |
pipe(other_builder) |
Append another CommandBuilder via a pipe and return a PipeBuilder. |
build() |
Turn this single command into an Executor, which exposes timeout/exit-code controls and run(). |
PipeBuilder
| Method |
Description |
pipe(other_builder) |
Attach another command to the current pipeline. |
build() |
Convert the pipeline into an Executor. |
Executor
| Method |
Description |
timeout(ms) |
Override the pipeline-wide timeout in milliseconds (Config::default_timeout_ms is used otherwise). |
cwd(path) |
Set the working directory for the entire pipeline. |
allow_exit_codes(array) |
Treat the listed exit codes as successes. |
run() |
Execute the pipeline and return #{ success, status, stdout, stderr, duration_ms }. |
run_stream(stdout_fn?, stderr_fn?) |
Stream stdout/stderr in real time (defaults to printing directly) and return the same result map. stdout / stderr in the result are empty strings. |
Handling results
run() (or run_stream()) is the terminal API. Both return #{ success, status, stdout, stderr, duration_ms }; check success (or inspect stderr) and raise your own error if needed. run_stream() streams stdout/stderr directly, so the stdout/stderr fields in the result are empty strings.
License
Dual-licensed under MIT or Apache-2.0.