1use crate::DisplayableValue;
2use cel_interpreter::objects::{Key, Map};
3use cel_interpreter::Value;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::sync::Arc;
7
8#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
9pub(crate) struct ExecutionContext {
10 pub(crate) variables: PassableMap,
11 pub(crate) expression: String,
12 pub(crate) computed: Option<HashMap<String, Vec<PassableValue>>>,
13 pub(crate) device: Option<HashMap<String, Vec<PassableValue>>>
14}
15
16#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
17pub struct PassableMap {
18 pub map: HashMap<String, PassableValue>,
19}
20
21#[derive(Serialize, Deserialize, Debug, Clone)]
22#[serde(tag = "type", content = "value")]
23pub enum PassableValue {
24 #[serde(rename = "list")]
25 List(Vec<PassableValue>),
26 #[serde(rename = "map")]
27 PMap(HashMap<String, PassableValue>),
28 #[serde(rename = "function")]
29 Function(String, Option<Box<PassableValue>>),
30 #[serde(rename = "int")]
31 Int(i64),
32 #[serde(rename = "uint")]
33 UInt(u64),
34 #[serde(rename = "float")]
35 Float(f64),
36 #[serde(rename = "string")]
37 String(String),
38 #[serde(rename = "bytes")]
39 Bytes(Vec<u8>),
40 #[serde(rename = "bool")]
41 Bool(bool),
42 #[serde(rename = "timestamp")]
43 Timestamp(i64),
44 Null,
45}
46
47impl PartialEq for PassableValue {
48 fn eq(&self, other: &Self) -> bool {
49 match (self, other) {
50 (PassableValue::PMap(a), PassableValue::PMap(b)) => a == b,
51 (PassableValue::List(a), PassableValue::List(b)) => a == b,
52 (PassableValue::Function(a1, a2), PassableValue::Function(b1, b2)) => {
53 a1 == b1 && a2 == b2
54 }
55 (PassableValue::Int(a), PassableValue::Int(b)) => a == b,
56 (PassableValue::UInt(a), PassableValue::UInt(b)) => a == b,
57 (PassableValue::Float(a), PassableValue::Float(b)) => a == b,
58 (PassableValue::String(a), PassableValue::String(b)) => a == b,
59 (PassableValue::Bytes(a), PassableValue::Bytes(b)) => a == b,
60 (PassableValue::Bool(a), PassableValue::Bool(b)) => a == b,
61 (PassableValue::Null, PassableValue::Null) => true,
62 (PassableValue::Timestamp(a), PassableValue::Timestamp(b)) => a == b,
63 (PassableValue::Int(a), PassableValue::UInt(b)) => a
65 .to_owned()
66 .try_into()
67 .map(|a: u64| a == *b)
68 .unwrap_or(false),
69 (PassableValue::Int(a), PassableValue::Float(b)) => (*a as f64) == *b,
70 (PassableValue::UInt(a), PassableValue::Int(b)) => a
71 .to_owned()
72 .try_into()
73 .map(|a: i64| a == *b)
74 .unwrap_or(false),
75 (PassableValue::UInt(a), PassableValue::Float(b)) => (*a as f64) == *b,
76 (PassableValue::Float(a), PassableValue::Int(b)) => *a == (*b as f64),
77 (PassableValue::Float(a), PassableValue::UInt(b)) => *a == (*b as f64),
78 (_, _) => false,
79 }
80 }
81}
82
83impl PassableValue {
84 pub fn to_cel(&self) -> Value {
85 match self {
86 PassableValue::List(list) => {
87 let mapped_list: Vec<Value> = list.iter().map(|item| item.to_cel()).collect();
88 Value::List(Arc::new(mapped_list))
89 }
90 PassableValue::PMap(map) => {
91 let mapped_map = map
92 .iter()
93 .map(|(k, v)| (Key::String(Arc::from(k.clone())), (*v).to_cel()))
94 .collect();
95 Value::Map(Map {
96 map: Arc::new(mapped_map),
97 })
98 }
99 PassableValue::Function(name, arg) => {
100 let mapped_arg = arg.as_ref().map(|arg| arg.to_cel());
101 Value::Function(Arc::from(name.clone()), mapped_arg.map(|v| Box::new(v)))
102 }
103 PassableValue::Int(i) => Value::Int(*i),
104 PassableValue::UInt(u) => Value::UInt(*u),
105 PassableValue::Float(f) => Value::Float(*f),
106 PassableValue::String(s) => Value::String(Arc::from(s.clone())),
107 PassableValue::Bytes(b) => Value::Bytes(Arc::from(b.clone())),
108 PassableValue::Bool(b) => Value::Bool(*b),
109 PassableValue::Timestamp(t) => Value::Int(*t),
110 PassableValue::Null => Value::Null,
111 }
112 }
113}
114
115fn key_to_string(key: Key) -> String {
116 match key {
117 Key::String(s) => (*s).clone(),
118 Key::Int(i) => i.to_string(),
119 Key::Uint(u) => u.to_string(),
120 Key::Bool(b) => b.to_string(),
121 }
122}
123impl DisplayableValue {
124 pub fn to_passable(&self) -> PassableValue {
125 match &self.0 {
126 Value::List(list) => {
127 let mapped_list: Vec<PassableValue> = list
128 .iter()
129 .map(|item| DisplayableValue(item.clone()).to_passable())
130 .collect();
131 PassableValue::List(mapped_list)
132 }
133 Value::Map(map) => {
134 let mapped_map: HashMap<String, PassableValue> = map
135 .map
136 .iter()
137 .map(|(k, v)| {
138 (
139 key_to_string(k.clone()),
140 DisplayableValue(v.clone()).to_passable(),
141 )
142 })
143 .collect();
144 PassableValue::PMap(mapped_map)
145 }
146 Value::Function(name, arg) => {
147 let mapped_arg = arg.as_ref().map(|arg| {
148 let arg = *arg.clone();
149 let arg = DisplayableValue(arg).to_passable();
150 Box::new(arg)
151 });
152 PassableValue::Function((**name).clone(), mapped_arg)
153 }
154 Value::Int(i) => PassableValue::Int(*i),
155 Value::UInt(u) => PassableValue::UInt(*u),
156 Value::Float(f) => PassableValue::Float(*f),
157 Value::String(s) => PassableValue::String((**s).clone()),
158 Value::Bytes(b) => PassableValue::Bytes((**b).clone()),
159 Value::Bool(b) => PassableValue::Bool(*b),
160 Value::Duration(_) => PassableValue::Null,
161 Value::Timestamp(t) => PassableValue::Timestamp(t.timestamp()),
162 Value::Null => PassableValue::Null,
163 }
164 }
165}