sparrow/tools/
code_exec.rs1use std::process::Command;
4
5pub fn execute_code(code: &str, language: &str, timeout_secs: u64) -> anyhow::Result<ExecResult> {
6 let tmpdir = std::env::temp_dir().join("sparrow_exec");
7 std::fs::create_dir_all(&tmpdir)?;
8
9 let (ext, runner, args): (&str, &str, Vec<&str>) = match language {
10 "python" | "py" => ("py", "python3", vec![]),
11 "javascript" | "js" => ("js", "node", vec![]),
12 "bash" | "sh" => ("sh", "bash", vec![]),
13 "ruby" | "rb" => ("rb", "ruby", vec![]),
14 _ => anyhow::bail!("Unsupported: {language}. Use python, js, bash, or ruby."),
15 };
16
17 let file = tmpdir.join(format!("code_{}.{}", uuid::Uuid::new_v4(), ext));
18 std::fs::write(&file, code)?;
19
20 let output = Command::new("timeout")
21 .arg(timeout_secs.to_string())
22 .arg(runner)
23 .args(&args)
24 .arg(&file)
25 .output()?;
26
27 Ok(ExecResult {
28 success: output.status.success(),
29 stdout: String::from_utf8_lossy(&output.stdout).to_string(),
30 stderr: String::from_utf8_lossy(&output.stderr).to_string(),
31 exit_code: output.status.code().unwrap_or(-1),
32 language: language.to_string(),
33 })
34}
35
36#[derive(Debug, Clone, serde::Serialize)]
37pub struct ExecResult {
38 pub success: bool,
39 pub stdout: String,
40 pub stderr: String,
41 pub exit_code: i32,
42 pub language: String,
43}