json_stream_parser/
lib.rs

1use serde_json::{json, Value};
2
3#[derive(Clone, Debug)]
4enum ObjectStatus {
5    // We are ready to start a new object.
6    Ready,
7    // We are in the beginning of a string, likely because we just received an opening quote.
8    StringQuoteOpen,
9    // We just finished a string, likely because we just received a closing quote.
10    StringQuoteClose,
11    // We are in the middle of a scalar value, likely because we just received a digit.
12    Scalar {
13        value_so_far: Vec<char>,
14    },
15    ScalarNumber {
16        value_so_far: Vec<char>,
17    },
18    // We just started a property, likely because we just received an opening brace or a comma in case of an existing object.
19    StartProperty,
20    // We are in the beginning of a key, likely because we just received a quote. We need to store the key_so_far because
21    // unlike the value, we cannot add the key to the object until it is complete.
22    KeyQuoteOpen {
23        key_so_far: Vec<char>,
24    },
25    // We just finished a key, likely because we just received a closing quote.
26    KeyQuoteClose {
27        key: Vec<char>,
28    },
29    // We just finished a key, likely because we just received a colon.
30    Colon {
31        key: Vec<char>,
32    },
33    // We are in the beginning of a value, likely because we just received a quote.
34    ValueQuoteOpen {
35        key: Vec<char>,
36        // We don't need to store the valueSoFar because we can add the value to the object immediately.
37    },
38    ValueQuoteClose,
39
40    // We are taking any value that is not a string. For these case we just store
41    // each character until we reach a comma or a closing brace and then we pare
42    // and add the value to the object.
43    ValueScalar {
44        key: Vec<char>,
45        value_so_far: Vec<char>,
46    },
47
48    // We just finished the object, likely because we just received a closing brace.
49    Closed,
50}
51
52// this function takes and existing object that we are building along with a single character as we as an address
53// to the current position in the object that we are in and returns the object with that character added along with
54// the new address.
55fn add_char_into_object(
56    object: &mut Value,
57    current_status: &mut ObjectStatus,
58    current_char: char,
59) -> Result<(), String> {
60    match (object, current_status, current_char) {
61        (val @ Value::Null, sts @ ObjectStatus::Ready, '"') => {
62            *val = json!("");
63            *sts = ObjectStatus::StringQuoteOpen;
64        }
65        (val @ Value::Null, sts @ ObjectStatus::Ready, '{') => {
66            *val = json!({});
67            *sts = ObjectStatus::StartProperty;
68        }
69        // ------ true ------
70        (val @ Value::Null, sts @ ObjectStatus::Ready, 't') => {
71            *val = json!(true);
72            *sts = ObjectStatus::Scalar {
73                value_so_far: vec!['t'],
74            };
75        }
76        (
77            Value::Bool(true),
78            ObjectStatus::Scalar {
79                ref mut value_so_far,
80            },
81            'r',
82        ) if *value_so_far == vec!['t'] => {
83            value_so_far.push('r');
84        }
85        (
86            Value::Bool(true),
87            ObjectStatus::Scalar {
88                ref mut value_so_far,
89            },
90            'u',
91        ) if *value_so_far == vec!['t', 'r'] => {
92            value_so_far.push('u');
93        }
94        (Value::Bool(true), sts @ ObjectStatus::Scalar { .. }, 'e') => {
95            *sts = ObjectStatus::Closed;
96        }
97        // ------ false ------
98        (val @ Value::Null, sts @ ObjectStatus::Ready, 'f') => {
99            *val = json!(false);
100            *sts = ObjectStatus::Scalar {
101                value_so_far: vec!['f'],
102            };
103        }
104        (
105            Value::Bool(false),
106            ObjectStatus::Scalar {
107                ref mut value_so_far,
108            },
109            'a',
110        ) if *value_so_far == vec!['f'] => {
111            value_so_far.push('a');
112        }
113        (
114            Value::Bool(false),
115            ObjectStatus::Scalar {
116                ref mut value_so_far,
117            },
118            'l',
119        ) if *value_so_far == vec!['f', 'a'] => {
120            value_so_far.push('l');
121        }
122        (
123            Value::Bool(false),
124            ObjectStatus::Scalar {
125                ref mut value_so_far,
126            },
127            's',
128        ) if *value_so_far == vec!['f', 'a', 'l'] => {
129            value_so_far.push('s');
130        }
131        (Value::Bool(false), sts @ ObjectStatus::Scalar { .. }, 'e') => {
132            *sts = ObjectStatus::Closed;
133        }
134        // ------ null ------
135        (val @ Value::Null, sts @ ObjectStatus::Ready, 'n') => {
136            *val = json!(null);
137            *sts = ObjectStatus::Scalar {
138                value_so_far: vec!['n'],
139            };
140        }
141        (
142            Value::Null,
143            ObjectStatus::Scalar {
144                ref mut value_so_far,
145            },
146            'u',
147        ) if *value_so_far == vec!['n'] => {
148            value_so_far.push('u');
149        }
150        (
151            Value::Null,
152            ObjectStatus::Scalar {
153                ref mut value_so_far,
154            },
155            'l',
156        ) if *value_so_far == vec!['n', 'u'] => {
157            value_so_far.push('l');
158        }
159        (Value::Null, sts @ ObjectStatus::Scalar { .. }, 'l') => {
160            *sts = ObjectStatus::Closed;
161        }
162        // ------ number ------
163        (val @ Value::Null, sts @ ObjectStatus::Ready, c @ '0'..='9') => {
164            *val = Value::Number(c.to_digit(10).unwrap().into());
165            *sts = ObjectStatus::ScalarNumber {
166                value_so_far: vec![c],
167            };
168        }
169        (val @ Value::Null, sts @ ObjectStatus::Ready, '-') => {
170            *val = Value::Number(0.into());
171            *sts = ObjectStatus::ScalarNumber {
172                value_so_far: vec!['-'],
173            };
174        }
175        (
176            Value::Number(ref mut num),
177            ObjectStatus::ScalarNumber {
178                ref mut value_so_far,
179            },
180            c @ '0'..='9',
181        ) => {
182            value_so_far.push(c);
183            // if there are any . in the value so far, then we need to parse the number as a float
184            if value_so_far.contains(&'.') {
185                let parsed_number = value_so_far
186                    .iter()
187                    .collect::<String>()
188                    .parse::<f64>()
189                    .unwrap();
190
191                if let Some(json_number) = serde_json::Number::from_f64(parsed_number) {
192                    *num = json_number;
193                }
194            } else {
195                let parsed_number = value_so_far
196                    .iter()
197                    .collect::<String>()
198                    .parse::<i64>()
199                    .unwrap();
200                *num = parsed_number.into();
201            }
202        }
203        (
204            Value::Number(_),
205            ObjectStatus::ScalarNumber {
206                ref mut value_so_far,
207            },
208            '.',
209        ) => {
210            value_so_far.push('.');
211        }
212        // ------ string ------
213        (Value::String(_str), sts @ ObjectStatus::StringQuoteOpen, '"') => {
214            *sts = ObjectStatus::StringQuoteClose;
215        }
216        (Value::String(str), sts @ ObjectStatus::StringQuoteOpen, char) => {
217            str.push(char);
218            *sts = ObjectStatus::StringQuoteOpen;
219        }
220        (Value::Object(_obj), sts @ ObjectStatus::StartProperty, '"') => {
221            *sts = ObjectStatus::KeyQuoteOpen { key_so_far: vec![] };
222        }
223        (Value::Object(ref mut obj), sts @ ObjectStatus::KeyQuoteOpen { .. }, '"') => {
224            if let ObjectStatus::KeyQuoteOpen { key_so_far } = sts.clone() {
225                *sts = ObjectStatus::KeyQuoteClose {
226                    key: key_so_far.clone(),
227                };
228                obj.insert(key_so_far.iter().collect::<String>(), Value::Null);
229            }
230        }
231        (Value::Object(_obj), ObjectStatus::KeyQuoteOpen { ref mut key_so_far }, char) => {
232            key_so_far.push(char);
233        }
234        (Value::Object(_obj), sts @ ObjectStatus::KeyQuoteClose { .. }, ':') => {
235            if let ObjectStatus::KeyQuoteClose { key } = sts.clone() {
236                *sts = ObjectStatus::Colon { key: key.clone() };
237            }
238        }
239        (Value::Object(_obj), ObjectStatus::Colon { .. }, ' ' | '\n') => {}
240        (Value::Object(ref mut obj), sts @ ObjectStatus::Colon { .. }, '"') => {
241            if let ObjectStatus::Colon { key } = sts.clone() {
242                *sts = ObjectStatus::ValueQuoteOpen { key: key.clone() };
243                // create an empty string for the value
244                obj.insert(key.iter().collect::<String>().clone(), json!(""));
245            }
246        }
247        // ------ Add String Value ------
248        (Value::Object(_obj), sts @ ObjectStatus::ValueQuoteOpen { .. }, '"') => {
249            *sts = ObjectStatus::ValueQuoteClose;
250        }
251        (Value::Object(ref mut obj), ObjectStatus::ValueQuoteOpen { key }, char) => {
252            let key_string = key.iter().collect::<String>();
253            let value = obj.get_mut(&key_string).unwrap();
254            match value {
255                Value::String(value) => {
256                    value.push(char);
257                }
258                _ => {
259                    return Err(format!("Invalid value type for key {}", key_string));
260                }
261            }
262        }
263
264        // ------ Add Scalar Value ------
265        (Value::Object(_obj), sts @ ObjectStatus::Colon { .. }, char) => {
266            if let ObjectStatus::Colon { key } = sts.clone() {
267                *sts = ObjectStatus::ValueScalar {
268                    key: key.clone(),
269                    value_so_far: vec![char],
270                };
271            }
272        }
273        (Value::Object(ref mut obj), sts @ ObjectStatus::ValueScalar { .. }, ',') => {
274            if let ObjectStatus::ValueScalar { key, value_so_far } = sts.clone() {
275                let key_string = key.iter().collect::<String>();
276                let value_string = value_so_far.iter().collect::<String>();
277                let value = match value_string.parse::<Value>() {
278                    Ok(value) => value,
279                    Err(e) => {
280                        return Err(format!("Invalid value for key {}: {}", key_string, e));
281                    }
282                };
283                obj.insert(key_string, value);
284                *sts = ObjectStatus::StartProperty;
285            }
286        }
287        (Value::Object(ref mut obj), sts @ ObjectStatus::ValueScalar { .. }, '}') => {
288            if let ObjectStatus::ValueScalar { key, value_so_far } = sts.clone() {
289                let key_string = key.iter().collect::<String>();
290                let value_string = value_so_far.iter().collect::<String>();
291                let value = match value_string.parse::<Value>() {
292                    Ok(value) => value,
293                    Err(e) => {
294                        return Err(format!("Invalid value for key {}: {}", key_string, e));
295                    }
296                };
297                obj.insert(key_string, value);
298                *sts = ObjectStatus::Closed;
299            }
300        }
301        (
302            Value::Object(_obj),
303            ObjectStatus::ValueScalar {
304                key: _key,
305                ref mut value_so_far,
306            },
307            char,
308        ) => {
309            // push the character into the value so far
310            value_so_far.push(char);
311        }
312
313        // ------ Finished taking value ------
314        (Value::Object(_obj), sts @ ObjectStatus::ValueQuoteClose, ',') => {
315            *sts = ObjectStatus::StartProperty;
316        }
317        (Value::Object(_obj), sts @ ObjectStatus::ValueQuoteClose, '}') => {
318            *sts = ObjectStatus::Closed;
319        }
320        // ------ white spaces ------
321        (_, _, ' ' | '\n') => {}
322        (_val, st, c) => {
323            return Err(format!("Invalid character {} status: {:?}", c, st));
324        }
325    }
326
327    Ok(())
328}
329
330pub fn parse_stream(json_string: &str) -> Result<Value, String> {
331    let mut out: Value = Value::Null;
332    let mut current_status = ObjectStatus::Ready;
333    for current_char in json_string.chars() {
334        println!(
335            "variables: {:?} {:?} {:?}",
336            out,
337            current_status.clone(),
338            current_char.to_string()
339        );
340        if let Err(e) = add_char_into_object(&mut out, &mut current_status, current_char) {
341            return Err(e);
342        }
343    }
344    return Ok(out);
345}
346
347pub struct JsonStreamParser {
348    object: Value,
349    current_status: ObjectStatus,
350}
351
352impl JsonStreamParser {
353    pub fn new() -> JsonStreamParser {
354        JsonStreamParser {
355            object: Value::Null,
356            current_status: ObjectStatus::Ready,
357        }
358    }
359
360    pub fn add_char(&mut self, current_char: char) -> Result<(), String> {
361        add_char_into_object(&mut self.object, &mut self.current_status, current_char)
362    }
363
364    pub fn get_result(&self) -> &Value {
365        &self.object
366    }
367}
368
369macro_rules! param_test {
370    ($($name:ident: $string:expr, $value:expr)*) => {
371    $(
372        mod $name {
373            use super::{parse_stream, JsonStreamParser};
374            use serde_json::{Value, json};
375
376            #[test]
377            fn simple() {
378                let string: &str = $string;
379                let value: Value = $value;
380                let result = parse_stream(&string);
381                assert_eq!(result.unwrap(), value);
382                let mut parser = JsonStreamParser::new();
383                for c in string.chars() {
384                    parser.add_char(c);
385                }
386                assert_eq!(parser.get_result(), &value);
387            }
388
389            #[test]
390            fn object_single_key_value() {
391                let string = $string;
392                let value = $value;
393                let raw_json = format!("{{\"key\": {}}}", string);
394                let expected = json!({"key": value});
395                let result = parse_stream(&raw_json);
396                assert_eq!(result.unwrap(), expected);
397                let mut parser = JsonStreamParser::new();
398                for c in raw_json.chars() {
399                    parser.add_char(c);
400                }
401                assert_eq!(parser.get_result(), &expected);
402            }
403
404            #[test]
405            fn object_multiple_key_value() {
406                let string = $string;
407                let value = $value;
408                let raw_json = format!("{{\"key1\": {}, \"key2\": {}}}", string, string);
409                let expected = json!({"key1": value, "key2": value});
410                let result = parse_stream(&raw_json);
411                assert_eq!(result.unwrap(), expected);
412                let mut parser = JsonStreamParser::new();
413                for c in raw_json.chars() {
414                    parser.add_char(c);
415                }
416                assert_eq!(parser.get_result(), &expected);
417            }
418
419            #[test]
420            fn object_multiple_key_value_with_blank_1() {
421                let string = $string;
422                let value = $value;
423                let raw_json = format!("{{ \"key1\": {}, \"key2\": {}}}", string, string);
424                let expected = json!({"key1": value, "key2": value});
425                let result = parse_stream(&raw_json);
426                assert_eq!(result.unwrap(), expected);
427                let mut parser = JsonStreamParser::new();
428                for c in raw_json.chars() {
429                    parser.add_char(c);
430                }
431                assert_eq!(parser.get_result(), &expected);
432            }
433
434            #[test]
435            fn object_multiple_key_value_with_blank_2() {
436                let string = $string;
437                let value = $value;
438                let raw_json = format!("{{\"key1\": {}, \"key2\": {} }}", string, string);
439                let expected = json!({"key1": value, "key2": value});
440                let result = parse_stream(&raw_json);
441                assert_eq!(result.unwrap(), expected);
442                let mut parser = JsonStreamParser::new();
443                for c in raw_json.chars() {
444                    parser.add_char(c);
445                }
446                assert_eq!(parser.get_result(), &expected);
447            }
448
449            #[test]
450            fn object_multiple_key_value_with_blank_3() {
451                let string = $string;
452                let value = $value;
453                let raw_json = format!("{{ 
454                    \"key1\": {} , 
455                     \"key2\": {} 
456                }}", string, string);
457                let expected = json!({"key1": value, "key2": value});
458                let result = parse_stream(&raw_json);
459                assert_eq!(result.unwrap(), expected);
460                let mut parser = JsonStreamParser::new();
461                for c in raw_json.chars() {
462                    parser.add_char(c);
463                }
464                assert_eq!(parser.get_result(), &expected);
465            }
466        }
467    )*
468    }
469}
470
471param_test! {
472    null: r#"null"#, Value::Null
473    true_value: r#"true"#, Value::Bool(true)
474    false_value: r#"false"#, Value::Bool(false)
475    empty_string: r#""""#, Value::String("".to_string())
476    single_character_string: r#""a""#, Value::String("a".to_string())
477    string_with_spaces: r#""a b c""#, Value::String("a b c".to_string())
478    string_with_space_at_end: r#""a b c ""#, Value::String("a b c ".to_string())
479    string_with_space_at_start: r#"" a b c""#, Value::String(" a b c".to_string())
480    string_with_space_at_start_and_end: r#"" a b c ""#, Value::String(" a b c ".to_string())
481    number: r#"1234567890"#, Value::Number(1234567890.into())
482    negative_number: r#"-1234567890"#, Value::Number((-1234567890).into())
483    zero: r#"0"#, Value::Number(0.into())
484    float: r#"123.456"#, Value::Number(serde_json::Number::from_f64(123.456).unwrap())
485    negative_float: r#"-123.456"#, Value::Number(serde_json::Number::from_f64(-123.456).unwrap())
486}