rl_lang/interpreter/stdlib/process/
exec.rs1use crate::{
2 ast::statements::TypeAnnotation,
3 interpreter::{evaluator::Evaluator, values::Value},
4 utils::{errors::Error, span::Span},
5};
6use std::process::Command;
7
8#[cfg(target_os = "windows")]
9fn shell_command(cmd: &str) -> Command {
10 let mut c = Command::new("cmd");
11 c.args(["/C", cmd]);
12 c
13}
14
15#[cfg(not(target_os = "windows"))]
16fn shell_command(cmd: &str) -> Command {
17 let mut c = Command::new("sh");
18 c.args(["-c", cmd]);
19 c
20}
21
22pub fn std_exec(eval: &mut Evaluator, cmd: String, span: Span) -> Result<Value, Error> {
23 let output = shell_command(&cmd)
24 .output()
25 .map_err(|e| eval.err(format!("exec(): failed to run \"{}\": {}", cmd, e), span))?;
26 let stdout = String::from_utf8_lossy(&output.stdout).to_string();
27 Ok(Value::String(stdout.trim_end_matches('\n').to_string()))
28}
29
30pub fn std_exec_code(eval: &mut Evaluator, cmd: String, span: Span) -> Result<Value, Error> {
31 let status = shell_command(&cmd).status().map_err(|e| {
32 eval.err(
33 format!("exec_code(): failed to run \"{}\": {}", cmd, e),
34 span,
35 )
36 })?;
37 Ok(Value::Integer(status.code().unwrap_or(-1) as i64))
38}
39
40pub fn std_exec_lines(eval: &mut Evaluator, cmd: String, span: Span) -> Result<Value, Error> {
41 let output = shell_command(&cmd).output().map_err(|e| {
42 eval.err(
43 format!("exec_lines(): failed to run \"{}\": {}", cmd, e),
44 span,
45 )
46 })?;
47 let stdout = String::from_utf8_lossy(&output.stdout).to_string();
48 let lines: Vec<Value> = stdout
49 .lines()
50 .map(|l| Value::String(l.to_string()))
51 .collect();
52 Ok(Value::Values {
53 items_type: TypeAnnotation::String,
54 items: lines,
55 })
56}