json_parse/
json_parse.rs

1use std::{fs::File, io::Read};
2
3use replacinator::Replacinator;
4
5#[derive(Debug)]
6struct JsonArray<'a> {
7    values: Vec<&'a mut str>,
8}
9
10fn main() {
11    let mut buf = String::new();
12    let _ = File::open("examples/test.json")
13        .unwrap()
14        .read_to_string(&mut buf)
15        .unwrap();
16
17    let json_values = Replacinator::new_in(&mut buf, parse_json_array);
18    dbg!(json_values);
19    println!("Buffer is now: {}", buf);
20}
21
22fn parse_json_array<'a>(src: &mut Replacinator<'a>) -> JsonArray<'a> {
23    let mut values = Vec::new();
24    assert_eq!(src.skip_char(), Some('['));
25    loop {
26        match src.skip_char() {
27            Some('"') => {
28                // Reset the replacinator to the beginning of this string
29                let _ = src.get_begin();
30                loop {
31                    match src
32                        .read_char()
33                        .expect("JSON value should not end in the middle of a string")
34                    {
35                        '\\' => match src
36                            .read_char()
37                            .expect("JSON value should not end in the middle of an escape sequence")
38                        {
39                            '"' => src.write_char('"'),
40                            '\\' => src.write_char('\\'),
41                            '/' => src.write_char('/'),
42                            'b' => src.write_char('\x08'),
43                            'f' => src.write_char('\x0c'),
44                            'n' => src.write_char('\n'),
45                            'r' => src.write_char('\r'),
46                            't' => src.write_char('\t'),
47                            'u' => {
48                                let mut res = 0;
49                                for _ in 0..4 {
50                                    let v = src
51                                        .read_char()
52                                        .expect("String ended in unicode")
53                                        .to_digit(16)
54                                        .expect("Invalid hex digit in escape");
55                                    res = res * 16 + v;
56                                }
57                                src.write_char(
58                                    std::char::from_u32(res).expect("Valid character code"),
59                                )
60                            }
61                            other => panic!("Invalid escape {:?}", other),
62                        },
63                        '"' => {
64                            values.push(src.get_begin());
65                            src.write_char('"');
66                            break;
67                        }
68                        other => src.write_char(other),
69                    }
70                }
71            }
72            Some(']') => break,
73            Some(' ') | Some('\n') | Some('\t') => (),
74            res => panic!(
75                r#"JSON array should be continued with '"' or ']', got {:?}"#,
76                res
77            ),
78        }
79    }
80    JsonArray { values }
81}