sal-rhai 0.1.0

SAL Rhai - Rhai scripting integration for the System Abstraction Layer
Documentation
//! Rhai wrappers for core engine functions
//!
//! This module provides Rhai wrappers for functions that interact with the Rhai engine itself.

use super::error::ToRhaiError;
use rhai::{Engine, EvalAltResult, NativeCallContext};
use sal_os as os;

/// Register core module functions with the Rhai engine
///
/// # Arguments
///
/// * `engine` - The Rhai engine to register the functions with
///
/// # Returns
///
/// * `Result<(), Box<EvalAltResult>>` - Ok if registration was successful, Err otherwise
pub fn register_core_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
    engine.register_fn("exec", exec);
    Ok(())
}

/// Execute a Rhai script from a URL, file, or string
///
/// # Arguments
///
/// * `context` - The native call context, used to access the Rhai engine
/// * `source` - The source of the script to execute. Can be a URL, a file path, or a string of code.
///
/// # Returns
///
/// * `Result<rhai::Dynamic, Box<EvalAltResult>>` - The result of the script execution
pub fn exec(context: NativeCallContext, source: &str) -> Result<rhai::Dynamic, Box<EvalAltResult>> {
    let content = if source.starts_with("http://") || source.starts_with("https://") {
        // If the source is a URL, download it to a temporary file
        let temp_dir = std::env::temp_dir();
        let file_name = source.split('/').last().unwrap_or("script.rhai");
        let dest_path = temp_dir.join(format!("{}-{}", uuid::Uuid::new_v4(), file_name));
        let dest_str = dest_path.to_str().unwrap();

        os::download_file(source, dest_str, 0).to_rhai_error()?;
        os::file_read(dest_str).to_rhai_error()?
    } else if os::exist(source) {
        // If the source is an existing file, read it
        os::file_read(source).to_rhai_error()?
    } else {
        // Otherwise, treat the source as the script content itself
        source.to_string()
    };

    // Execute the script content
    context.engine().eval(&content)
}