platelet/
for_loop_runner.rs1use serde_json::Value;
2
3use crate::{
4 expression_eval::{eval, EvalError},
5 for_loop_parser::ForLoop,
6 types::{type_of, Type},
7};
8
9#[derive(Debug, PartialEq)]
10pub enum Error {
11 TypeMismatch { expected: Vec<Type>, found: Type },
12 Eval(EvalError),
13}
14
15pub(crate) fn for_loop_runner(
16 for_loop: &ForLoop,
17 base_context: &Value,
18) -> Result<Vec<Value>, Error> {
19 match for_loop {
20 ForLoop::Simple(id, exp) => {
21 let val = eval(exp, base_context).map_err(Error::Eval)?;
22 match val {
23 Value::Array(vec) => Ok(vec
24 .iter()
25 .map(|v| {
26 let mut obj = base_context.as_object().unwrap().clone();
27 obj.insert(id.clone(), v.clone());
28 Value::Object(obj)
29 })
30 .collect()),
31 _ => Err(Error::TypeMismatch {
32 expected: vec![Type::Array],
33 found: type_of(&val),
34 }),
35 }
36 }
37 ForLoop::IndexedObjectOrKeyValue(ids, exp) => {
38 let val = eval(exp, base_context).map_err(Error::Eval)?;
39 match val {
40 Value::Array(vec) => {
41 let (id, indexer) = ids;
42 Ok(vec
43 .iter()
44 .enumerate()
45 .map(|(index, v)| {
46 let mut obj = base_context.as_object().unwrap().clone();
47 obj.insert(id.clone(), v.clone());
48 obj.insert(indexer.clone(), index.clone().into());
49 Value::Object(obj)
50 })
51 .collect())
52 }
53 Value::Object(vec) => {
54 let (key_id, value_id) = ids;
55 Ok(vec
56 .iter()
57 .map(|(k, v)| {
58 let mut obj = base_context.as_object().unwrap().clone();
59 obj.insert(key_id.clone(), k.clone().into());
60 obj.insert(value_id.clone(), v.clone());
61 Value::Object(obj)
62 })
63 .collect())
64 }
65 _ => Err(Error::TypeMismatch {
66 expected: vec![Type::Array, Type::Object],
67 found: type_of(&val),
68 }),
69 }
70 }
71 ForLoop::IndexedKeyValue(ids, exp) => {
72 let val = eval(exp, base_context).map_err(Error::Eval)?;
73 match val {
74 Value::Object(vec) => {
75 let (key_id, value_id, indexer) = ids;
76 Ok(vec
77 .iter()
78 .enumerate()
79 .map(|(index, (k, v))| {
80 let mut obj = base_context.as_object().unwrap().clone();
81 obj.insert(key_id.clone(), k.clone().into());
82 obj.insert(value_id.clone(), v.clone());
83 obj.insert(indexer.clone(), index.clone().into());
84 Value::Object(obj)
85 })
86 .collect())
87 }
88 _ => Err(Error::TypeMismatch {
89 expected: vec![Type::Object],
90 found: type_of(&val),
91 }),
92 }
93 }
94 }
95}