o- 0.4.1

Multi-Engine JavaScript Runtime
Documentation
use std::process::Command;

use o_core::{
    engine::JSEngine,
    error::{JSError, JSResult},
};

pub struct BinEngine {
    path: String
}

impl BinEngine {
    pub fn new(path: String) -> Self {
        Self {
            path
        }
    }
}


impl JSEngine for BinEngine {
    fn run(&self, code: &str, filename: &str) -> Result<o_core::error::JSResult, o_core::error::JSError> {
        let result = Command::new(self.path.clone())
            .arg("-c")
            .arg(filename)
            .arg(code)
            .output()
            .map_err(|source| {
                JSError::internal(format!(
                    "failed to execute toolchain binary `{}`: {source}",
                    self.path
                ))
                .with_filename(filename)
                .with_source(code)
            })?;

        if !result.status.success() {
            let stderr = String::from_utf8_lossy(&result.stderr);
            let message = if stderr.trim().is_empty() {
                format!(
                    "toolchain binary `{}` exited with status {}",
                    self.path, result.status
                )
            } else {
                format!(
                    "toolchain binary `{}` failed: {}",
                    self.path,
                    stderr.trim()
                )
            };

            return Err(JSError::runtime(message)
                .with_filename(filename)
                .with_source(code));
        }

        let output = String::from_utf8(result.stdout).map_err(|source| {
            JSError::internal(format!(
                "toolchain binary `{}` returned invalid UTF-8 output: {source}",
                self.path
            ))
            .with_filename(filename)
            .with_source(code)
        })?;
        Ok(JSResult::String(output))
    }
}