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(), #[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}