1use 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
6pub type Compressed = (Vec<String>, Key);
8
9pub 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
54pub 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 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 let num_str = &v_str[2..];
69 if !num_str.contains('.') && !num_str.contains('e') && !num_str.contains('E') {
70 if let Ok(i) = num_str.parse::<i64>() {
72 return Value::Number(Number::from(i));
73 }
74 if let Ok(u) = num_str.parse::<u64>() {
76 return Value::Number(Number::from(u));
77 }
78 }
79 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 Value::String(decode_str(v_str))
87 }
88}
89
90pub fn decompress(c: Compressed) -> Value {
92 let (values, root) = c;
93 decode(&values, &root)
94}