jsonm_bugfixed/
unpacker.rs1extern 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
13const 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, 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 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 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 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(&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 return Err(UnpackerError {
267 cause: "no stored value".to_owned(),
268 })
269 }
271 };
272 let json = string.to_owned();
273 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(&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(&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(&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(&mut self, value: &Value) {
345 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 pub fn set_max_dict_size(&mut self, value: u64) {
356 self.max_dict_size = value;
357 }
358}