compress_json_rs/
core.rs

1// Removed unused import of HashMap
2use serde_json::{Value, Map, Number};
3use crate::encode::{decode_bool, decode_key, decode_num, decode_str};
4use crate::memory::{make_memory, mem_to_values, add_value, Key};
5
6/// Compressed representation: (values array, root key)
7pub type Compressed = (Vec<String>, Key);
8
9/// Compress a JSON object into its compressed representation
10pub fn compress(o: &Value) -> Compressed {
11    let mut mem = make_memory();
12    let root = add_value(&mut mem, o);
13    let values = mem_to_values(&mem);
14    (values, root)
15}
16
17fn decode_object(values: &Vec<String>, s: &str) -> Value {
18    if s == "o|" {
19        return Value::Object(Map::new());
20    }
21    let parts: Vec<&str> = s.split('|').collect();
22    let key_id = parts[1];
23    let mut keys_val = decode(values, key_id);
24    let mut keys: Vec<String> = match keys_val {
25        Value::String(ref k) => vec![k.clone()],
26        Value::Array(arr) => arr.into_iter().map(|v| match v {
27            Value::String(s) => s,
28            other => panic!("Invalid key type in decode_object: {:?}", other),
29        }).collect(),
30        other => panic!("Invalid keys in decode_object: {:?}", other),
31    };
32    let mut map = Map::new();
33    for (i, part) in parts.iter().enumerate().skip(2) {
34        let v = decode(values, part);
35        let key = keys[i - 2].clone();
36        map.insert(key, v);
37    }
38    Value::Object(map)
39}
40
41fn decode_array(values: &Vec<String>, s: &str) -> Value {
42    if s == "a|" {
43        return Value::Array(Vec::new());
44    }
45    let parts: Vec<&str> = s.split('|').collect();
46    let mut arr = Vec::with_capacity(parts.len() - 1);
47    for part in parts.iter().skip(1) {
48        let v = decode(values, part);
49        arr.push(v);
50    }
51    Value::Array(arr)
52}
53
54/// Decode a single key into a JSON Value
55pub fn decode(values: &Vec<String>, key: &str) -> Value {
56    if key.is_empty() || key == "_" {
57        return Value::Null;
58    }
59    let id = decode_key(key);
60    let v_str = &values[id];
61    // Determine value type by prefix and decode accordingly
62    if v_str.starts_with("b|") {
63        Value::Bool(decode_bool(v_str))
64    } else if v_str.starts_with("o|") {
65        decode_object(values, v_str)
66    } else if v_str.starts_with("n|") {
67        // Numeric: preserve integers when no decimal or exponent
68        let num_str = &v_str[2..];
69        if !num_str.contains('.') && !num_str.contains('e') && !num_str.contains('E') {
70            // try signed integer
71            if let Ok(i) = num_str.parse::<i64>() {
72                return Value::Number(Number::from(i));
73            }
74            // try unsigned integer
75            if let Ok(u) = num_str.parse::<u64>() {
76                return Value::Number(Number::from(u));
77            }
78        }
79        // fallback to float
80        let num = decode_num(v_str);
81        Value::Number(Number::from_f64(num).expect("Invalid number"))
82    } else if v_str.starts_with("a|") {
83        decode_array(values, v_str)
84    } else {
85        // default to string
86        Value::String(decode_str(v_str))
87    }
88}
89
90/// Decompress a compressed representation back into JSON
91pub fn decompress(c: Compressed) -> Value {
92    let (values, root) = c;
93    decode(&values, &root)
94}