Skip to main content

payload/
payload.rs

1use serde_json::Value;
2use std::collections::HashMap;
3use std::error::Error;
4
5pub fn add_context(key: &str, json_str: &str, context: &mut HashMap<String, String>) {
6    let json: Value = match serde_json::from_str(json_str) {
7        Ok(json) => json,
8        Err(_) => {
9            context.insert(key.to_string(), json_str.to_string());
10            return;
11        }
12    };
13    let json_obj = json.as_object().unwrap();
14    let context_obj = context.entry(key.to_string()).or_insert_with(String::new);
15    let nested_obj = build_nested_object(json_obj);
16    let nested_str = serde_json::to_string(&nested_obj).unwrap();
17    context_obj.push_str(&format!(r#"{}"#, nested_str));
18}
19
20fn build_nested_object(json: &serde_json::Map<String, Value>) -> serde_json::Map<String, Value> {
21    let mut nested_obj = serde_json::Map::new();
22    for (key, value) in json.iter() {
23        match value {
24            Value::Null => {
25                nested_obj.insert(key.clone(), Value::Null);
26            }
27            Value::Bool(b) => {
28                nested_obj.insert(key.clone(), Value::Bool(*b));
29            }
30            Value::Number(n) => {
31                nested_obj.insert(key.clone(), Value::Number(n.clone()));
32            }
33            Value::String(s) => {
34                nested_obj.insert(key.clone(), Value::String(s.clone()));
35            }
36            Value::Array(arr) => {
37                let nested_arr = arr
38                    .iter()
39                    .map(|v| match v {
40                        Value::Null => Value::Null,
41                        Value::Bool(b) => Value::Bool(*b),
42                        Value::Number(n) => Value::Number(n.clone()),
43                        Value::String(s) => Value::String(s.clone()),
44                        Value::Array(_) => Value::Array(build_nested_array(v.as_array().unwrap())),
45                        Value::Object(_) => {
46                            Value::Object(build_nested_object(v.as_object().unwrap()))
47                        }
48                    })
49                    .collect();
50                nested_obj.insert(key.clone(), Value::Array(nested_arr));
51            }
52            Value::Object(obj) => {
53                let nested_obj2 = build_nested_object(obj);
54                nested_obj.insert(key.clone(), Value::Object(nested_obj2));
55            }
56        }
57    }
58    nested_obj
59}
60
61fn build_nested_array(json: &[Value]) -> Vec<Value> {
62    json.iter()
63        .map(|v| match v {
64            Value::Null => Value::Null,
65            Value::Bool(b) => Value::Bool(*b),
66            Value::Number(n) => Value::Number(n.clone()),
67            Value::String(s) => Value::String(s.clone()),
68            Value::Array(arr) => Value::Array(build_nested_array(arr)),
69            Value::Object(obj) => Value::Object(build_nested_object(obj)),
70        })
71        .collect()
72}
73
74pub fn to_json(context: &HashMap<String, String>) -> HashMap<String, serde_json::Value> {
75    let mut json = HashMap::new();
76    for (key, value) in context.iter() {
77        let parsed_value =
78            serde_json::from_str(value).unwrap_or_else(|_| Value::String(value.clone()));
79        json.insert(key.to_string(), parsed_value);
80    }
81    json
82}
83
84fn main() -> Result<(), Box<dyn Error>> {
85    let mut ctx = HashMap::new();
86
87    add_context("send_email", r#"{"status": "success"}"#, &mut ctx);
88    let engine = exprimo::Evaluator::new(
89        to_json(&ctx),
90        HashMap::new(), // custom_functions
91    );
92
93    let expr = r#"send_email.status === 'success' "#;
94
95    let result = engine.evaluate(expr)?;
96
97    println!("send_email.status === 'success' => {}", result);
98
99    Ok(())
100}