Skip to main content

o_/
binengine.rs

1use std::process::Command;
2
3use o_core::{
4    engine::JSEngine,
5    error::{JSError, JSResult},
6};
7
8pub struct BinEngine {
9    path: String,
10}
11
12impl BinEngine {
13    pub fn new(path: String) -> Self {
14        Self { path }
15    }
16}
17
18impl JSEngine for BinEngine {
19    fn run(
20        &self,
21        code: &str,
22        filename: &str,
23    ) -> Result<o_core::error::JSResult, o_core::error::JSError> {
24        let result = Command::new(self.path.clone())
25            .arg("-c")
26            .arg(filename)
27            .arg(code)
28            .output()
29            .map_err(|source| {
30                JSError::internal(format!(
31                    "failed to execute toolchain binary `{}`: {source}",
32                    self.path
33                ))
34                .with_filename(filename)
35                .with_source(code)
36            })?;
37
38        if !result.status.success() {
39            let stderr = String::from_utf8_lossy(&result.stderr);
40            let message = if stderr.trim().is_empty() {
41                format!(
42                    "toolchain binary `{}` exited with status {}",
43                    self.path, result.status
44                )
45            } else {
46                format!("toolchain binary `{}` failed: {}", self.path, stderr.trim())
47            };
48
49            return Err(JSError::runtime(message)
50                .with_filename(filename)
51                .with_source(code));
52        }
53
54        let output = String::from_utf8(result.stdout).map_err(|source| {
55            JSError::internal(format!(
56                "toolchain binary `{}` returned invalid UTF-8 output: {source}",
57                self.path
58            ))
59            .with_filename(filename)
60            .with_source(code)
61        })?;
62        Ok(JSResult::String(output))
63    }
64}