jsonm_bugfixed/
unpacker.rs

1extern crate regex;
2extern crate serde;
3extern crate serde_json;
4
5use self::regex::Regex;
6use self::serde::Deserialize;
7use serde_json::Value;
8use std::collections::HashMap;
9use std::error::Error;
10use std::fmt;
11use std::vec::Vec;
12
13//const OLD_MESSAGE: i32 = -99;
14const MIN_DICT_INDEX: u64 = 3;
15const TYPE_ARRAY: i64 = 0;
16const TYPE_VALUE: i64 = 1;
17const TYPE_STRING: i64 = 2;
18const MAX_PACK_COMPLEX_OBJECT_SIZE: usize = 12;
19
20#[derive(Default, Debug)]
21pub struct Unpacker {
22    // dict: HashMap<u64, String>,
23    dict: HashMap<u64, Value>,
24    dict_index: u64,
25    sequence_id: i64,
26    max_dict_size: u64,
27    pending_unpacks: Vec<i32>,
28}
29
30#[derive(Debug, Clone)]
31pub struct UnpackerError {
32    pub cause: String,
33}
34
35impl fmt::Display for UnpackerError {
36    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37        write!(f, "UnpackerError")
38    }
39}
40
41impl Error for UnpackerError {
42    fn description(&self) -> &str {
43        "Unpacker Error"
44    }
45
46    fn cause(&self) -> Option<&dyn Error> {
47        None
48    }
49}
50
51impl Unpacker {
52    pub fn new() -> Unpacker {
53        Unpacker {
54            sequence_id: -1,
55            max_dict_size: 2000,
56            dict_index: MIN_DICT_INDEX,
57            ..Default::default()
58        }
59    }
60
61    /// Unpack an packed object to its original input.
62    pub fn unpack<T>(&mut self, packed_object: &Value) -> Result<T, UnpackerError>
63    where
64        for<'de> T: Deserialize<'de>,
65    {
66        if packed_object.is_null() {
67            return match serde_json::from_value(Value::Null) {
68                Ok(v) => Ok(v),
69                Err(_err) => Err(UnpackerError {
70                    cause: "wrong end type for Value::Null, use Value type instead".to_owned(),
71                }),
72            };
73        };
74
75        let packed_arr = match packed_object.as_array() {
76            Some(packed_arr) => packed_arr,
77            None => {
78                return Err(UnpackerError {
79                    cause: "packed value expected".to_owned(),
80                })
81            }
82        };
83
84        if !packed_arr[packed_arr.len() - 1].is_number() {
85            return Err(UnpackerError {
86                cause: "packed value expected".to_owned(),
87            });
88        };
89
90        let value = &packed_arr[packed_arr.len() - 1];
91        let remote_sequence_id = match value.as_i64() {
92            Some(v) => v,
93            None => {
94                return Err(UnpackerError {
95                    cause: "packed value expected".to_owned(),
96                })
97            }
98        };
99
100        if remote_sequence_id == 0 {
101            self.dict_index = MIN_DICT_INDEX;
102        } else if remote_sequence_id != (self.sequence_id + 1) {
103            return Err(UnpackerError {
104                cause: "message unpacked out of sequence or already unpacked".to_owned(),
105            });
106        };
107
108        self.sequence_id = remote_sequence_id;
109        let unpacked = match self.unpack_object(&json!(packed_arr[..(packed_arr.len() - 1)])) {
110            Ok(result) => result,
111            Err(err) => return Err(err),
112        };
113
114        let result: T = match serde_json::from_value(unpacked) {
115            Ok(result) => result,
116            Err(_err) => {
117                return Err(UnpackerError {
118                    cause: "unable to unpack to specific type".to_owned(),
119                })
120            }
121        };
122        Ok(result)
123    }
124
125    /// Unpack an object to a string.
126    pub fn unpack_string(&mut self, packed_object: &Value) -> Result<String, UnpackerError> {
127        match packed_object.as_array() {
128            Some(arr) => {
129                if arr[0] == TYPE_STRING {
130                    return self.unpack(packed_object);
131                }
132
133                match self.unpack::<Value>(packed_object) {
134                    Ok(s) => Ok(s.to_string()),
135                    Err(err) => Err(err),
136                }
137            }
138            None => match self.unpack::<Value>(packed_object) {
139                Ok(s) => Ok(s.to_string()),
140                Err(err) => Err(err),
141            },
142        }
143    }
144
145    fn unpack_object(&mut self, packed_object: &Value) -> Result<Value, UnpackerError> {
146        if packed_object.is_null() {
147            return Ok(Value::Null);
148        };
149
150        if !packed_object.is_array() {
151            return self.unpack_value(packed_object);
152        }
153
154        // if packed_object == &json!([0]) {
155        //     return Ok(json!({}));
156        // }
157
158        let packed_array = match packed_object.as_array() {
159            Some(packed_array) => packed_array,
160            None => {
161                return Err(UnpackerError {
162                    cause: "wrong packed object".to_owned(),
163                })
164            }
165        };
166
167        if packed_array.len() == 0 { return Ok(json!({})); }
168        let type_value = &packed_array[0];
169        let type_id = match type_value.as_i64() {
170            Some(i) => i,
171            None => -1,
172        };
173
174        if type_id == TYPE_ARRAY {
175            return packed_array[1..]
176                .iter()
177                .map(|v| self.unpack_object(&v))
178                .collect();
179        }
180        if type_id == TYPE_STRING {
181            return match packed_array[1..]
182                .iter()
183                .map(|v| self.unpack_object(&v))
184                .collect::<Result<Value, _>>()
185            {
186                Ok(arr) => {
187                    let vec = match arr.as_array() {
188                        Some(a) => a,
189                        None => {
190                            return Err(UnpackerError {
191                                cause: "expected array, got something else".to_owned(),
192                            })
193                        }
194                    };
195                    Ok(json!(vec.iter().fold("".to_owned(), |acc, x| {
196                        if acc.is_empty() {
197                            x.as_str().unwrap().to_owned()
198                        } else {
199                            acc + "\n" + x.as_str().unwrap()
200                        }
201                    })))
202                }
203                Err(err) => return Err(err),
204            };
205        }
206        if type_id == TYPE_VALUE {
207            return self.unpack_value(&packed_array[1]);
208        }
209
210        let mut contains_unmemoised = false;
211        let mut processed_object: Vec<Value> = Vec::new();
212        for item in packed_array {
213            if item.is_object() || item.is_array() {
214                let value = match self.unpack_object(&item) {
215                    Ok(v) => v,
216                    Err(err) => return Err(err),
217                };
218                contains_unmemoised = true;
219                processed_object.push(value);
220            } else {
221                if !item.is_number() {
222                    contains_unmemoised = true;
223                }
224                let value = match self.unpack_value(&item) {
225                    Ok(v) => v,
226                    Err(err) => return Err(err),
227                };
228
229                processed_object.push(value);
230            }
231        }
232
233        let mut result: HashMap<String, Value> = HashMap::new();
234        let key_count = processed_object.len() / 2;
235        for i in 0..key_count {
236            let key_value = &processed_object[i];
237            let key = match processed_object[i].as_str() {
238                Some(s) => s.to_string(),
239                None => key_value.to_string(),
240            };
241            result.insert(key, processed_object[i + key_count].clone());
242        }
243
244        let json_result = json!(result);
245        if !contains_unmemoised && packed_array.len() <= MAX_PACK_COMPLEX_OBJECT_SIZE {
246            // self.add_to_dict_str(&json_result.to_string());
247            self.add_to_dict(&json_result);
248        }
249
250        Ok(json_result)
251    }
252
253    fn unpack_value(&mut self, packed_object: &Value) -> Result<Value, UnpackerError> {
254        if packed_object.is_number() {
255            return match packed_object.as_i64() {
256                Some(v) => {
257                    if v < 0 {
258                        return Ok(json!(v * -1));
259                    }
260                    let index = packed_object.as_u64().unwrap();
261                    let string = match self.dict.get(&index) {
262                        Some(s) => s,
263                        None => {
264                            println!("Wrong Index: {:?}", index);
265                            // println!("Index: {:?}\nDict: {:#?}", index, self.dict);
266                            return Err(UnpackerError {
267                                cause: "no stored value".to_owned(),
268                            })
269                            // return Ok(json!(null));
270                        }
271                    };
272                    let json = string.to_owned();
273                    // let json: serde_json::Value = match serde_json::from_str(&string) {
274                    //     Ok(parsed) => parsed,
275                    //     Err(_err) => json!(string),
276                    // };
277
278                    Ok(json)
279                }
280                None => Err(UnpackerError {
281                    cause: "unknown".to_owned(),
282                }),
283            };
284        };
285
286        if packed_object.is_string() {
287            let string = match packed_object.as_str() {
288                Some(s) => s,
289                None => {
290                    return Err(UnpackerError {
291                        cause: "unknown".to_owned(),
292                    })
293                }
294            };
295
296            let re = Regex::new(r"^-?[0-9]+\.").unwrap();
297            if re.is_match(string) {
298                let _p: Value = match string.parse::<f64>() {
299                    Ok(parse_number) => {
300                        // self.add_to_dict_str(string);
301                        self.add_to_dict(&json!(parse_number));
302                        return Ok(json!(parse_number));
303                    }
304                    Err(_err) => Value::Null,
305                };
306            };
307
308            let re = Regex::new(r"^-?[0-9\.]").unwrap();
309            if re.is_match(string) {
310                let _p: Value = match string.parse::<i64>() {
311                    Ok(parse_number) => {
312                        // self.add_to_dict_str(string);
313                        self.add_to_dict(&json!(parse_number));
314                        return Ok(json!(parse_number));
315                    }
316                    Err(_err) => Value::Null,
317                };
318            };
319
320            let value = if !string.is_empty() && &string[0..1] == "~" {
321                &string[1..]
322            } else {
323                string
324            };
325
326            // self.add_to_dict_str(&json!(value).to_string());
327            self.add_to_dict(&json!(value));
328            return Ok(json!(value));
329        }
330
331        self.add_to_dict(packed_object);
332        Ok(json!(packed_object))
333    }
334
335    // fn add_to_dict_str(&mut self, str_value: &str) {
336    //     // println!("Index: {}\tValue: {}", self.dict_index, str_value.to_owned());
337    //     self.dict.insert(self.dict_index, json!(str_value.to_owned()));
338    //     self.dict_index += 1;
339    //     if self.dict_index >= (self.max_dict_size + MIN_DICT_INDEX) {
340    //         self.dict_index = MIN_DICT_INDEX;
341    //     }
342    // }
343
344    fn add_to_dict(&mut self, value: &Value) {
345        // println!("Index: {}\tValue: {}", self.dict_index, value.to_owned());
346        self.dict.insert(self.dict_index, value.to_owned());
347        self.dict_index += 1;
348        if self.dict_index >= (self.max_dict_size + MIN_DICT_INDEX) {
349            self.dict_index = MIN_DICT_INDEX;
350        }
351    }
352
353    /// Set the maximum dictionary size. Must match the dictionary size used by the packer.
354    /// Default - 2000.
355    pub fn set_max_dict_size(&mut self, value: u64) {
356        self.max_dict_size = value;
357    }
358}