1use crate::context::input::InputContext;
3use crate::evaluator::Evaluator;
4use crate::expression::Expression;
5use crate::input::Input;
6use pel::expression::Expression as PelExpression;
7use pel::runtime::value::Value as PelValue;
8use pel::runtime::{Evaluation, Runtime, RuntimeError};
9use thiserror::Error;
10
11pub struct ScriptingEngine {}
13
14impl ScriptingEngine {
15 pub fn script(expression: &Expression) -> ScriptParser {
17 ScriptParser::new(expression)
18 }
19}
20
21pub struct ScriptParser<'a> {
23 expression: &'a Expression,
24 input_context: InputContext,
25}
26
27impl<'a> ScriptParser<'a> {
28 pub(crate) fn new(expression: &'a Expression) -> Self {
29 Self {
30 expression,
31 input_context: InputContext::default(),
32 }
33 }
34
35 pub fn input(mut self, input: Input) -> Self {
37 match input {
38 Input::Payload(fmt) => self.input_context.set_payload_input(fmt),
39 Input::Vars(vars) => {
40 self.input_context.push_var_input(vars);
41 }
42 Input::Attributes => {
43 self.input_context.set_attributes_input();
44 }
45 Input::Authentication => self.input_context.set_authentication_input(),
46 }
47 self
48 }
49
50 pub fn compile(self) -> Result<Script, ScriptError> {
52 let result = Runtime::new()
53 .eval_with_context(&self.expression.expression, &self.input_context)
54 .map_err(ScriptError::Error)?;
55
56 match result {
57 Evaluation::Complete(_, v) => Ok(Script::new(None, Some(v), self.input_context)),
58 Evaluation::Partial(e) => Ok(Script::new(Some(e), None, self.input_context)),
59 }
60 }
61}
62
63#[derive(Error, Debug)]
65pub enum ScriptError {
66 #[error("Error compiling expression: {0}")]
68 Error(RuntimeError),
69}
70
71#[derive(Debug, Clone)]
73pub struct Script {
74 evaluation: Option<PelExpression>,
75 result: Option<PelValue>,
76 context: InputContext,
77}
78
79impl Script {
80 pub(crate) fn new(
81 evaluation: Option<PelExpression>,
82 result: Option<PelValue>,
83 context: InputContext,
84 ) -> Self {
85 Self {
86 evaluation,
87 result,
88 context,
89 }
90 }
91
92 pub fn evaluator(&self) -> Evaluator {
94 Evaluator::new(self.evaluation.clone(), self.result.clone(), &self.context)
95 }
96}