1use std::collections::HashMap;
2use std::sync::{Mutex};
3use once_cell::sync::Lazy;
4use serde_json::Value;
5
6use crate::tree::{parse_schema, schema_to_tree, Tree};
7
8pub static PLANTED_PARSE_TREES:Lazy<Mutex<HashMap<u64, Tree>>> = Lazy::new(|| {
9 let hm:HashMap<u64, Tree> = HashMap::new();
10 Mutex::new(hm)
11});
12
13pub fn is_tree_planted(unique_tree_id:u64) -> bool {
14 PLANTED_PARSE_TREES.lock().unwrap().contains_key(&unique_tree_id)
15}
16
17pub fn plant_tree_schema(unique_tree_id:u64, schema: Tree) -> i32 {
18 let mut hm = PLANTED_PARSE_TREES.lock().unwrap();
19 hm.insert(unique_tree_id, schema);
20 0
21}
22
23pub fn plant_tree(unique_tree_id:u64, schema: Value) -> i32 {
24 plant_tree_schema(unique_tree_id, schema_to_tree(schema))
25}
26
27pub fn parse_tree(
28 unique_tree_id: u64,
29 data: &[u8]
30) -> Result<Value, String>
31{
32 let schema:Tree = {
33 let reg_map = PLANTED_PARSE_TREES.lock().unwrap();
35 let sr = reg_map.get(&unique_tree_id).ok_or(format!("No tree with unique_tree_id {} found", unique_tree_id))?;
36 let so = sr.clone();
37 so
38 };
39
40 let mut previous_values = HashMap::new();
41 let parse_ret = parse_schema(&data, &schema.branches, false, &mut previous_values);
42 match parse_ret {
43 Ok((parsed_json, _parse_pos)) => {
44 Ok(parsed_json)
45 }
46 Err((partially_parsed_json, errstr)) => {
47 println!("WARNING: (normal for infinite loops or loops beyond bytes provided) parse_schema() failed with error: {errstr}, returning partially_parsed_json struct");
48 Ok(partially_parsed_json)
49 }
50 }
51}
52
53#[cfg(test)]
54use serde_json::json;
55#[cfg(test)]
56use crate::utils::hex_to_bin;
57
58#[test]
59fn test_simple_packet() {
60 const TREE_ID:u64 = 1;
61 let data = hex_to_bin("01 00 E8 03");
62 plant_tree(
63 TREE_ID,
64 json!({
65 "branches": [
66 { "name": "fix_status", "type": "u8" },
67 { "name": "rcr", "type": "u8" },
68 { "name": "millisecond", "type": "u16_le" }
69 ]
70 })
71 );
72 let parsed_json = parse_tree(TREE_ID, &data).unwrap();
73 assert_eq!(parsed_json, json!({
74 "fix_status": 1,
75 "rcr": 0,
76 "millisecond": 1000
77 }));
78}