Skip to main content

vynil_core/
shell.rs

1//! Shell execution helpers.
2//!
3//! `run` / `get_out` are the Rust APIs; `shell_run` / `shell_output` are the Rhai
4//! bindings gated behind the `shell` feature (plus `rhai` for the bindings).
5
6use crate::{Error, Result};
7#[cfg(feature = "rhai")] use crate::{RhaiRes, rhai_err};
8#[cfg(feature = "rhai")] use rhai::Engine;
9use std::process::{Command, Output, Stdio};
10
11/// Run `sh -c <command>` inheriting stdout/stderr. Returns the raw [`Output`].
12pub fn run(command: String) -> Result<Output> {
13    Command::new("sh")
14        .arg("-c")
15        .arg(command)
16        .stdout(Stdio::inherit())
17        .stderr(Stdio::inherit())
18        .output()
19        .map_err(Error::Stdio)
20}
21
22#[cfg(feature = "rhai")]
23pub fn rhai_run(command: String) -> RhaiRes<i64> {
24    let out = run(command).map_err(rhai_err)?;
25    Ok(i64::from(out.status.code().unwrap_or(0)))
26}
27
28/// Run `sh -c <command>` capturing stdout/stderr. Returns the raw [`Output`].
29pub fn get_out(command: String) -> Result<Output> {
30    Command::new("sh")
31        .arg("-c")
32        .arg(command)
33        .stdout(Stdio::piped())
34        .stderr(Stdio::piped())
35        .output()
36        .map_err(Error::Stdio)
37}
38
39#[cfg(feature = "rhai")]
40pub fn rhai_get_stdout(command: String) -> RhaiRes<String> {
41    let out = get_out(command).map_err(rhai_err)?;
42    if !out.status.success() {
43        Err(rhai_err(Error::Other(format!(
44            "Command failed, rc={}",
45            out.status.code().unwrap_or(-1)
46        ))))
47    } else if !out.stderr.is_empty() {
48        let err = String::from_utf8(out.stderr).map_err(|e| rhai_err(Error::UTF8(e)))?;
49        tracing::warn!(err);
50        Err(rhai_err(Error::Other(format!("Command had stderr : {}", err))))
51    } else {
52        let output = String::from_utf8(out.stdout).map_err(|e| rhai_err(Error::UTF8(e)))?;
53        Ok(output)
54    }
55}
56
57#[cfg(feature = "rhai")]
58pub fn shell_rhai_register(engine: &mut Engine) {
59    engine
60        .register_fn("shell_run", rhai_run)
61        .register_fn("shell_output", rhai_get_stdout);
62}