payload/
payload.rs

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