1use std::collections::HashMap;
2use std::fmt::{Display, Formatter};
3use std::str::FromStr;
4
5use bumpalo::Bump;
6use hashbrown::hash_map::DefaultHashBuilder;
7use hashbrown::BumpWrapper;
8
9use rust_decimal::Decimal;
10use serde_json::{Map, Number, Value};
11
12#[derive(Debug)]
13pub enum Variable<'a> {
14 Null,
15 Bool(bool),
16 Int(i64),
17 Number(Decimal),
18 String(&'a str),
19 Array(&'a [&'a Variable<'a>]),
20 Object(hashbrown::HashMap<&'a str, &'a Variable<'a>, DefaultHashBuilder, BumpWrapper<'a>>),
21 Interval {
22 left_bracket: &'a str,
23 right_bracket: &'a str,
24 left: &'a Variable<'a>,
25 right: &'a Variable<'a>,
26 },
27}
28
29impl<'a> Display for Variable<'a> {
30 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
31 write!(f, "{self:?}")
32 }
33}
34
35impl<'a> Clone for Variable<'a> {
36 fn clone(&self) -> Self {
37 match self {
38 Variable::Null => Variable::Null,
39 Variable::Bool(b) => Variable::Bool((*b).clone()),
40 Variable::Int(i) => Variable::Int((*i).clone()),
41 Variable::Number(n) => Variable::Number(n.clone()),
42 Variable::String(s) => Variable::String(s.clone()),
43 Variable::Array(a) => Variable::Array(a.clone()),
44 Variable::Object(o) => Variable::Object(o.clone()),
45 Variable::Interval {
46 left_bracket,
47 right_bracket,
48 left,
49 right,
50 } => Variable::Interval {
51 left_bracket: left_bracket.clone(),
52 right_bracket: right_bracket.clone(),
53 left: left.clone(),
54 right: right.clone(),
55 },
56 }
57 }
58}
59
60impl<'a> Variable<'a> {
61 pub fn empty_object_in(bump: &'a Bump) -> Self {
62 Variable::Object(hashbrown::HashMap::new_in(BumpWrapper(bump)))
63 }
64
65 pub fn from_serde(v: &Value, bump: &'a Bump) -> Self {
66 match v {
67 Value::String(str) => Variable::String(bump.alloc_str(str)),
68 Value::Number(f) => {
69 Variable::Number(Decimal::from_str_exact(f.to_string().as_str()).unwrap())
70 }
71 Value::Bool(b) => Variable::Bool((*b).clone()),
72 Value::Array(v) => {
73 let mut arr: Vec<&'a Variable> = Vec::with_capacity(v.len());
74 for i in v {
75 arr.push(bump.alloc(Variable::from_serde(i, bump)));
76 }
77
78 Variable::Array(bump.alloc_slice_copy(arr.as_slice()))
79 }
80 Value::Object(bt) => {
81 let mut tree: hashbrown::HashMap<&'a str, &'a Variable, _, _> =
82 hashbrown::HashMap::new_in(BumpWrapper(bump));
83 for k in bt.keys() {
84 let v = bt.get(k).unwrap();
85 tree.insert(
86 bump.alloc_str(k.as_str()),
87 bump.alloc(Variable::from_serde(v, bump)),
88 );
89 }
90
91 Variable::Object(tree)
92 }
93 Value::Null => Variable::Null,
94 }
95 }
96}
97
98#[derive(Debug)]
99pub enum Opcode<'a> {
100 Push(Variable<'a>),
101 Pop,
102 Rot,
103 Fetch,
104 FetchField(&'a str),
105 FetchEnv(&'a str),
106 Negate,
107 Not,
108 Equal,
109 Jump(usize),
110 JumpIfTrue(usize),
111 JumpIfFalse(usize),
112 JumpIfEnd(usize),
113 JumpBackward(usize),
114 In,
115 Less,
116 More,
117 LessOrEqual,
118 MoreOrEqual,
119 Abs,
120 Average,
121 Min,
122 Max,
123 Round,
124 Floor,
125 Ceil,
126 Sum,
127 Random,
128 Add,
129 Subtract,
130 Multiply,
131 Divide,
132 Modulo,
133 Exponent,
134 Interval {
135 left_bracket: &'a str,
136 right_bracket: &'a str,
137 },
138 Contains,
139 DateManipulation(&'a str),
140 Uppercase,
141 Lowercase,
142 StartsWith,
143 EndsWith,
144 Slice,
145 Array,
146 Len,
147 ParseTime,
148 ParseDuration,
149 IncrementIt,
150 IncrementCount,
151 GetCount,
152 GetLen,
153 Pointer,
154 Begin,
155 End,
156}
157
158impl<'a> Display for Opcode<'a> {
159 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
160 write!(f, "{:?}", self)
161 }
162}
163
164#[derive(Debug, PartialEq, Clone)]
165pub enum ExecResult {
166 Null,
167 Bool(bool),
168 Number(Decimal),
169 String(String),
170 Array(Vec<ExecResult>),
171 Object(HashMap<String, ExecResult>),
172}
173
174impl TryFrom<&Variable<'_>> for ExecResult {
175 type Error = ();
176
177 fn try_from(value: &Variable) -> Result<Self, Self::Error> {
178 match value {
179 Variable::Null => Ok(ExecResult::Null),
180 Variable::Bool(b) => Ok(ExecResult::Bool((*b).clone())),
181 Variable::Number(n) => Ok(ExecResult::Number(*n)),
182 Variable::String(s) => Ok(ExecResult::String(s.to_string())),
183 Variable::Array(arr) => {
184 let mut v = Vec::<ExecResult>::with_capacity(arr.len());
185 for i in *arr {
186 v.push(ExecResult::try_from(*i)?)
187 }
188
189 Ok(ExecResult::Array(v))
190 }
191 Variable::Object(obj) => {
192 let mut t = HashMap::new();
193
194 for k in obj.keys() {
195 let v = *obj.get(k).ok_or_else(|| ())?;
196 t.insert(k.to_string(), ExecResult::try_from(v)?);
197 }
198
199 Ok(ExecResult::Object(t))
200 }
201 _ => Err(()),
202 }
203 }
204}
205
206impl ExecResult {
207 pub fn to_variable<'a>(&self, bump: &'a Bump) -> Result<&'a Variable<'a>, ()> {
208 match self {
209 ExecResult::Null => Ok(bump.alloc(Variable::Null)),
210 ExecResult::Bool(b) => Ok(bump.alloc(Variable::Bool((*b).clone()))),
211 ExecResult::Number(n) => Ok(bump.alloc(Variable::Number(*n))),
212 ExecResult::String(str) => Ok(bump.alloc(Variable::String(bump.alloc_str(str)))),
213 ExecResult::Array(arr) => {
214 let mut v = Vec::<&'a Variable<'a>>::with_capacity(arr.len());
215 for i in arr {
216 v.push(i.to_variable(bump)?)
217 }
218
219 Ok(bump.alloc(Variable::Array(bump.alloc_slice_copy(v.as_slice()))))
220 }
221 ExecResult::Object(obj) => {
222 let mut t = hashbrown::HashMap::<&'a str, _, _, _>::new_in(BumpWrapper(bump));
223
224 for k in obj.keys() {
225 let v = obj.get(k).ok_or_else(|| ())?;
226 t.insert(bump.alloc_str(k), v.to_variable(bump)?);
227 }
228
229 Ok(bump.alloc(Variable::Object(t)))
230 }
231 }
232 }
233
234 pub fn to_value(&self) -> Result<Value, ()> {
235 match self {
236 ExecResult::Null => Ok(Value::Null),
237 ExecResult::Bool(b) => Ok(Value::Bool((*b).clone())),
238 ExecResult::Number(n) => Ok(Value::Number(
239 Number::from_str(n.to_string().as_str()).map_err(|_| ())?,
240 )),
241 ExecResult::String(s) => Ok(Value::String(s.clone())),
242 ExecResult::Array(arr) => {
243 let mut v = Vec::<Value>::with_capacity(arr.len());
244 for i in arr {
245 v.push(i.to_value()?)
246 }
247
248 Ok(Value::Array(v))
249 }
250 ExecResult::Object(obj) => {
251 let mut t = Map::new();
252
253 for k in obj.keys() {
254 let v = obj.get(k).ok_or_else(|| ())?;
255 t.insert(k.to_string(), v.to_value()?);
256 }
257
258 Ok(Value::Object(t))
259 }
260 }
261 }
262
263 pub fn bool(&self) -> Result<bool, ()> {
264 match self {
265 ExecResult::Bool(b) => Ok((*b).clone()),
266 _ => Err(()),
267 }
268 }
269}