1use crate::models::{PassableMap, PassableValue};
2use cel_parser::Member::{Attribute, Fields, Index};
3use cel_parser::{ArithmeticOp, Atom, Expression, Member, RelationOp, UnaryOp};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::sync::Arc;
7
8#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
9pub(crate) struct ASTExecutionContext {
10 pub(crate) variables: PassableMap,
11 pub(crate) expression: JSONExpression,
12 pub(crate) computed: Option<HashMap<String, Vec<PassableValue>>>,
13 pub(crate) device: Option<HashMap<String, Vec<PassableValue>>>
14}
15
16#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
17#[serde(tag = "type", content = "value")]
18pub enum JSONRelationOp {
19 LessThan,
20 LessThanEq,
21 GreaterThan,
22 GreaterThanEq,
23 Equals,
24 NotEquals,
25 In,
26}
27
28#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
29#[serde(tag = "type", content = "value")]
30pub enum JSONArithmeticOp {
31 Add,
32 Subtract,
33 Divide,
34 Multiply,
35 Modulus,
36}
37
38#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
39#[serde(tag = "type", content = "value")]
40pub enum JSONUnaryOp {
41 Not,
42 DoubleNot,
43 Minus,
44 DoubleMinus,
45}
46
47#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
48#[serde(tag = "type", content = "value")]
49pub enum JSONExpression {
50 Arithmetic(Box<JSONExpression>, JSONArithmeticOp, Box<JSONExpression>),
51 Relation(Box<JSONExpression>, JSONRelationOp, Box<JSONExpression>),
52 Ternary(
53 Box<JSONExpression>,
54 Box<JSONExpression>,
55 Box<JSONExpression>,
56 ),
57 Or(Box<JSONExpression>, Box<JSONExpression>),
58 And(Box<JSONExpression>, Box<JSONExpression>),
59 Unary(JSONUnaryOp, Box<JSONExpression>),
60 Member(Box<JSONExpression>, Box<JSONMember>),
61 FunctionCall(
62 Box<JSONExpression>,
63 Option<Box<JSONExpression>>,
64 Vec<JSONExpression>,
65 ),
66 List(Vec<JSONExpression>),
67 Map(Vec<(JSONExpression, JSONExpression)>),
68 Atom(JSONAtom),
69 Ident(String),
70}
71
72#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
73#[serde(tag = "type", content = "value")]
74pub enum JSONMember {
75 Attribute(String),
76 Index(Box<JSONExpression>),
77 Fields(Vec<(String, JSONExpression)>),
78}
79
80#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
81#[serde(tag = "type", content = "value")]
82pub enum JSONAtom {
83 Int(i64),
84 UInt(u64),
85 Float(f64),
86 String(String),
87 Bytes(Vec<u8>),
88 Bool(bool),
89 Null,
90}
91
92impl From<JSONRelationOp> for RelationOp {
94 fn from(op: JSONRelationOp) -> Self {
95 match op {
96 JSONRelationOp::LessThan => RelationOp::LessThan,
97 JSONRelationOp::LessThanEq => RelationOp::LessThanEq,
98 JSONRelationOp::GreaterThan => RelationOp::GreaterThan,
99 JSONRelationOp::GreaterThanEq => RelationOp::GreaterThanEq,
100 JSONRelationOp::Equals => RelationOp::Equals,
101 JSONRelationOp::NotEquals => RelationOp::NotEquals,
102 JSONRelationOp::In => RelationOp::In,
103 }
104 }
105}
106
107impl From<JSONArithmeticOp> for ArithmeticOp {
108 fn from(op: JSONArithmeticOp) -> Self {
109 match op {
110 JSONArithmeticOp::Add => ArithmeticOp::Add,
111 JSONArithmeticOp::Subtract => ArithmeticOp::Subtract,
112 JSONArithmeticOp::Divide => ArithmeticOp::Divide,
113 JSONArithmeticOp::Multiply => ArithmeticOp::Multiply,
114 JSONArithmeticOp::Modulus => ArithmeticOp::Modulus,
115 }
116 }
117}
118
119impl From<JSONUnaryOp> for UnaryOp {
120 fn from(op: JSONUnaryOp) -> Self {
121 match op {
122 JSONUnaryOp::Not => UnaryOp::Not,
123 JSONUnaryOp::DoubleNot => UnaryOp::DoubleNot,
124 JSONUnaryOp::Minus => UnaryOp::Minus,
125 JSONUnaryOp::DoubleMinus => UnaryOp::DoubleMinus,
126 }
127 }
128}
129
130impl From<JSONExpression> for Expression {
131 fn from(expr: JSONExpression) -> Self {
132 match expr {
133 JSONExpression::Arithmetic(left, op, right) => Expression::Arithmetic(
134 Box::new((*left).into()),
135 op.into(),
136 Box::new((*right).into()),
137 ),
138 JSONExpression::Relation(left, op, right) => Expression::Relation(
139 Box::new((*left).into()),
140 op.into(),
141 Box::new((*right).into()),
142 ),
143 JSONExpression::Ternary(cond, true_expr, false_expr) => Expression::Ternary(
144 Box::new((*cond).into()),
145 Box::new((*true_expr).into()),
146 Box::new((*false_expr).into()),
147 ),
148 JSONExpression::Or(left, right) => {
149 Expression::Or(Box::new((*left).into()), Box::new((*right).into()))
150 }
151 JSONExpression::And(left, right) => {
152 Expression::And(Box::new((*left).into()), Box::new((*right).into()))
153 }
154 JSONExpression::Unary(op, expr) => {
155 Expression::Unary(op.into(), Box::new((*expr).into()))
156 }
157 JSONExpression::Member(expr, member) => {
158 Expression::Member(Box::new((*expr).into()), Box::new((*member).into()))
159 }
160 JSONExpression::FunctionCall(func, optional_expr, args) => Expression::FunctionCall(
161 Box::new((*func).into()),
162 optional_expr.map(|e| Box::new((*e).into())),
163 args.into_iter().map(|e| e.into()).collect(),
164 ),
165 JSONExpression::List(items) => {
166 Expression::List(items.into_iter().map(|e| e.into()).collect())
167 }
168 JSONExpression::Map(items) => Expression::Map(
169 items
170 .into_iter()
171 .map(|(k, v)| (k.into(), v.into()))
172 .collect(),
173 ),
174 JSONExpression::Atom(atom) => Expression::Atom(atom.into()),
175 JSONExpression::Ident(s) => Expression::Ident(Arc::new(s)),
176 }
177 }
178}
179
180impl From<JSONMember> for Member {
181 fn from(member: JSONMember) -> Self {
182 match member {
183 JSONMember::Attribute(s) => Attribute(Arc::new(s)),
184 JSONMember::Index(expr) => Index(Box::new((*expr).into())),
185 JSONMember::Fields(fields) => Fields(
186 fields
187 .into_iter()
188 .map(|(k, v)| (Arc::new(k), v.into()))
189 .collect(),
190 ),
191 }
192 }
193}
194
195impl From<JSONAtom> for Atom {
196 fn from(atom: JSONAtom) -> Self {
197 match atom {
198 JSONAtom::Int(i) => Atom::Int(i),
199 JSONAtom::UInt(u) => Atom::UInt(u),
200 JSONAtom::Float(f) => Atom::Float(f),
201 JSONAtom::String(s) => Atom::String(Arc::new(s)),
202 JSONAtom::Bytes(b) => Atom::Bytes(Arc::new(b)),
203 JSONAtom::Bool(b) => Atom::Bool(b),
204 JSONAtom::Null => Atom::Null,
205 }
206 }
207}
208
209impl From<Expression> for JSONExpression {
210 fn from(expr: Expression) -> Self {
211 match expr {
212 Expression::Arithmetic(left, op, right) => JSONExpression::Arithmetic(
213 Box::new((*left).into()),
214 op.into(),
215 Box::new((*right).into()),
216 ),
217 Expression::Relation(left, op, right) => JSONExpression::Relation(
218 Box::new((*left).into()),
219 op.into(),
220 Box::new((*right).into()),
221 ),
222 Expression::Ternary(cond, true_expr, false_expr) => JSONExpression::Ternary(
223 Box::new((*cond).into()),
224 Box::new((*true_expr).into()),
225 Box::new((*false_expr).into()),
226 ),
227 Expression::Or(left, right) => {
228 JSONExpression::Or(Box::new((*left).into()), Box::new((*right).into()))
229 }
230 Expression::And(left, right) => {
231 JSONExpression::And(Box::new((*left).into()), Box::new((*right).into()))
232 }
233 Expression::Unary(op, expr) => {
234 JSONExpression::Unary(op.into(), Box::new((*expr).into()))
235 }
236 Expression::Member(expr, member) => {
237 JSONExpression::Member(Box::new((*expr).into()), Box::new((*member).into()))
238 }
239 Expression::FunctionCall(func, optional_expr, args) => JSONExpression::FunctionCall(
240 Box::new((*func).into()),
241 optional_expr.map(|e| Box::new((*e).into())),
242 args.into_iter().map(|e| e.into()).collect(),
243 ),
244 Expression::List(items) => {
245 JSONExpression::List(items.into_iter().map(|e| e.into()).collect())
246 }
247 Expression::Map(items) => JSONExpression::Map(
248 items
249 .into_iter()
250 .map(|(k, v)| (k.into(), v.into()))
251 .collect(),
252 ),
253 Expression::Atom(atom) => JSONExpression::Atom(atom.into()),
254 Expression::Ident(s) => JSONExpression::Ident((*s).clone()),
255 }
256 }
257}
258
259impl From<RelationOp> for JSONRelationOp {
261 fn from(op: RelationOp) -> Self {
262 match op {
263 RelationOp::LessThan => JSONRelationOp::LessThan,
264 RelationOp::LessThanEq => JSONRelationOp::LessThanEq,
265 RelationOp::GreaterThan => JSONRelationOp::GreaterThan,
266 RelationOp::GreaterThanEq => JSONRelationOp::GreaterThanEq,
267 RelationOp::Equals => JSONRelationOp::Equals,
268 RelationOp::NotEquals => JSONRelationOp::NotEquals,
269 RelationOp::In => JSONRelationOp::In,
270 }
271 }
272}
273
274impl From<ArithmeticOp> for JSONArithmeticOp {
275 fn from(op: ArithmeticOp) -> Self {
276 match op {
277 ArithmeticOp::Add => JSONArithmeticOp::Add,
278 ArithmeticOp::Subtract => JSONArithmeticOp::Subtract,
279 ArithmeticOp::Divide => JSONArithmeticOp::Divide,
280 ArithmeticOp::Multiply => JSONArithmeticOp::Multiply,
281 ArithmeticOp::Modulus => JSONArithmeticOp::Modulus,
282 }
283 }
284}
285
286impl From<UnaryOp> for JSONUnaryOp {
287 fn from(op: UnaryOp) -> Self {
288 match op {
289 UnaryOp::Not => JSONUnaryOp::Not,
290 UnaryOp::DoubleNot => JSONUnaryOp::DoubleNot,
291 UnaryOp::Minus => JSONUnaryOp::Minus,
292 UnaryOp::DoubleMinus => JSONUnaryOp::DoubleMinus,
293 }
294 }
295}
296
297impl From<Member> for JSONMember {
298 fn from(member: Member) -> Self {
299 match member {
300 Attribute(s) => JSONMember::Attribute((*s).clone()),
301 Index(expr) => JSONMember::Index(Box::new((*expr).into())),
302 Fields(fields) => JSONMember::Fields(
303 fields
304 .into_iter()
305 .map(|(k, v)| ((*k).clone(), v.into()))
306 .collect(),
307 ),
308 }
309 }
310}
311
312impl From<Atom> for JSONAtom {
313 fn from(atom: Atom) -> Self {
314 match atom {
315 Atom::Int(i) => JSONAtom::Int(i),
316 Atom::UInt(u) => JSONAtom::UInt(u),
317 Atom::Float(f) => JSONAtom::Float(f),
318 Atom::String(s) => JSONAtom::String((*s).clone()),
319 Atom::Bytes(b) => JSONAtom::Bytes((*b).clone()),
320 Atom::Bool(b) => JSONAtom::Bool(b),
321 Atom::Null => JSONAtom::Null,
322 }
323 }
324}
325
326#[cfg(test)]
327mod tests {
328 use super::*;
329 use cel_interpreter::Program;
330 use cel_parser::parser::ExpressionParser;
331
332 #[test]
333 fn test_ast_serializing() {
334 let expr = Expression::And(
336 Box::new(Expression::Relation(
337 Box::new(Expression::Arithmetic(
338 Box::new(Expression::Atom(Atom::Int(5))),
339 ArithmeticOp::Add,
340 Box::new(Expression::Atom(Atom::Int(3))),
341 )),
342 RelationOp::GreaterThan,
343 Box::new(Expression::Atom(Atom::Int(7))),
344 )),
345 Box::new(Expression::Relation(
346 Box::new(Expression::FunctionCall(
347 Box::new(Expression::Member(
348 Box::new(Expression::Ident(Arc::new("name".to_string()))),
349 Box::new(Attribute(Arc::new("length".to_string()))),
350 )),
351 None,
352 vec![],
353 )),
354 RelationOp::In,
355 Box::new(Expression::List(vec![
356 Expression::Atom(Atom::Int(5)),
357 Expression::Atom(Atom::Int(10)),
358 Expression::Atom(Atom::Int(15)),
359 ])),
360 )),
361 );
362
363 let json_expr: JSONExpression = expr.clone().into();
365
366 let json_string = serde_json::to_string_pretty(&json_expr).unwrap();
368
369 println!("JSON representation:");
370 println!("{}", json_string);
371
372 let text = "platform.myMethod(\"test\") == platform.name && user.test == 1";
373 let program = ExpressionParser::new().parse(text).unwrap();
374 let program: JSONExpression = program.into();
375 let serialized = serde_json::to_string_pretty(&program).unwrap();
376 println!("-----------–\n\n\n{}--------------\n\n", serialized);
377 let deserialized_json_expr: JSONExpression = serde_json::from_str(&json_string).unwrap();
379
380 let deserialized_expr: Expression = deserialized_json_expr.into();
382
383 println!("\nDeserialized Expression:");
384 println!("{:?}", deserialized_expr);
385
386 assert_eq!(expr, deserialized_expr);
388 println!("\nOriginal and deserialized expressions are equal!");
389 }
390}