1use crate::context::Context;
2use phlow_sdk::prelude::*;
3use phs::ScriptError;
4use rhai::{Engine, Scope, plugin::*, serde::to_dynamic};
5use std::collections::HashMap;
6use std::sync::Arc;
7
8#[derive(Debug, Clone)]
9pub struct Script {
10 pub script: phs::Script,
11}
12
13impl Script {
14 pub fn try_build(engine: Arc<Engine>, script: &Value) -> Result<Self, ScriptError> {
15 let script = phs::Script::try_build(engine, script)?;
16 Ok(Self { script })
17 }
18
19 pub fn evaluate(&self, context: &Context) -> Result<Value, ScriptError> {
20 let mut scope = Scope::new();
21
22 let steps: Dynamic =
23 to_dynamic(context.get_steps().clone()).map_err(ScriptError::EvalError)?;
24 let main: Dynamic =
25 to_dynamic(context.get_main().clone()).map_err(ScriptError::EvalError)?;
26 let payload: Dynamic =
27 to_dynamic(context.get_payload().clone()).map_err(ScriptError::EvalError)?;
28 let input: Dynamic =
29 to_dynamic(context.get_input().clone()).map_err(ScriptError::EvalError)?;
30 let setup: Dynamic =
31 to_dynamic(context.get_setup().clone()).map_err(ScriptError::EvalError)?;
32 let tests: Dynamic =
33 to_dynamic(context.get_tests().clone()).map_err(ScriptError::EvalError)?;
34
35 scope.push_constant("tests", tests);
36 scope.push_constant("steps", steps);
37 scope.push_constant("main", main);
38 scope.push_constant("payload", payload);
39 scope.push_constant("input", input);
40 scope.push_constant("setup", setup);
41
42 self.script.evaluate_from_scope(&mut scope)
43 }
44
45 pub fn compiled_debug(&self) -> Value {
46 let mut map = HashMap::new();
47 let mut compiled = HashMap::new();
48 for (index, code) in self.script.compiled_sources() {
49 compiled.insert(index.to_string(), code.to_value());
50 }
51 map.insert("template".to_string(), self.script.compiled_template());
52 map.insert("compiled".to_string(), compiled.to_value());
53 map.insert("expanded".to_string(), self.script.compiled_value());
54 map.to_value()
55 }
56}