rhai-process

Crates.iorhai-process
lib.rsrhai-process
version0.1.3
created_at2025-11-17 17:27:57.352486+00
updated_at2025-11-23 12:31:43.593648+00
descriptionExpose safe process-execution helpers to Rhai scripts.
homepagehttps://github.com/nakkiy/rhai-process
repositoryhttps://github.com/nakkiy/rhai-process
max_upload_size
id1937251
size69,365
(nakkiy)

documentation

https://docs.rs/rhai-process

README

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.

Commit count: 0

cargo fmt