Skip to main content

gridline_engine/engine/
eval.rs

1use rhai::Engine;
2use std::sync::Arc;
3
4use super::{AST, Dynamic, Grid};
5
6/// Create a Rhai engine with built-ins registered.
7pub fn create_engine(grid: Arc<Grid>) -> Engine {
8    let mut engine = Engine::new();
9    crate::builtins::register_builtins(&mut engine, grid);
10    engine
11}
12
13/// Create a Rhai engine with built-ins registered.
14/// Optionally compiles custom functions from the provided script.
15/// Returns the engine, compiled AST (if any), and any error message.
16pub fn create_engine_with_functions(
17    grid: Arc<Grid>,
18    custom_script: Option<&str>,
19) -> (Engine, Option<AST>, Option<String>) {
20    let engine = create_engine(grid);
21
22    let (ast, error) = if let Some(script) = custom_script {
23        match engine.compile(script) {
24            Ok(ast) => (Some(ast), None),
25            Err(e) => (None, Some(format!("Error in custom functions: {}", e))),
26        }
27    } else {
28        (None, None)
29    };
30
31    (engine, ast, error)
32}
33
34/// Evaluate a formula, optionally with custom functions AST.
35pub fn eval_with_functions(
36    engine: &Engine,
37    formula: &str,
38    custom_ast: Option<&AST>,
39) -> Result<Dynamic, String> {
40    if let Some(ast) = custom_ast {
41        match engine.compile(formula) {
42            Ok(formula_ast) => {
43                let merged = ast.clone().merge(&formula_ast);
44                engine.eval_ast(&merged).map_err(|e| e.to_string())
45            }
46            Err(e) => Err(e.to_string()),
47        }
48    } else {
49        engine.eval(formula).map_err(|e| e.to_string())
50    }
51}