zen_engine/nodes/expression/
mod.rs

1use crate::model::ExpressionNodeContent;
2use crate::nodes::result::NodeResult;
3use ahash::HashMap;
4use std::rc::Rc;
5
6use crate::nodes::context::{NodeContext, NodeContextExt};
7use crate::nodes::definition::NodeHandler;
8use zen_expression::variable::{ToVariable, Variable};
9use zen_expression::Isolate;
10use zen_types::decision::TransformAttributes;
11
12#[derive(Debug, Clone)]
13pub struct ExpressionNodeHandler;
14
15pub type ExpressionNodeData = ExpressionNodeContent;
16pub type ExpressionNodeTrace = HashMap<Rc<str>, ExpressionNodeTraceItem>;
17
18impl NodeHandler for ExpressionNodeHandler {
19    type NodeData = ExpressionNodeData;
20    type TraceData = ExpressionNodeTrace;
21
22    fn transform_attributes(
23        &self,
24        ctx: &NodeContext<Self::NodeData, Self::TraceData>,
25    ) -> Option<TransformAttributes> {
26        Some(ctx.node.transform_attributes.clone())
27    }
28
29    async fn handle(&self, ctx: NodeContext<Self::NodeData, Self::TraceData>) -> NodeResult {
30        let result = Variable::empty_object();
31        let mut isolate = Isolate::new();
32        isolate.set_environment(ctx.input.depth_clone(1));
33
34        for expression in ctx.node.expressions.iter() {
35            if expression.key.is_empty() || expression.value.is_empty() {
36                continue;
37            }
38
39            let value = isolate
40                .run_standard(&expression.value)
41                .with_node_context(&ctx, |_| {
42                    format!(r#"Failed to evaluate expression: "{}""#, &expression.value)
43                })?;
44            ctx.trace(|trace| {
45                trace.insert(
46                    Rc::from(&*expression.key),
47                    ExpressionNodeTraceItem {
48                        result: value.clone(),
49                    },
50                );
51            });
52
53            isolate.update_environment(|env| {
54                let Some(environment) = env else {
55                    return;
56                };
57
58                let key = format!("$.{}", &expression.key);
59                let _ = environment.dot_insert(key.as_str(), value.depth_clone(2));
60            });
61
62            result.dot_insert(&expression.key, value);
63        }
64
65        ctx.success(result)
66    }
67}
68
69#[derive(Debug, Clone, ToVariable)]
70pub struct ExpressionNodeTraceItem {
71    result: Variable,
72}