dirty_json/
lib.rs

1use json_tools::{Buffer, BufferType, Lexer, TokenType};
2
3pub fn fix(json: &str) -> String {
4    let bytes = json.as_bytes();
5    let mut fixed = Vec::with_capacity(bytes.len());
6    let mut last_token_type = TokenType::Invalid;
7    for token in Lexer::new(json.bytes(), BufferType::Bytes(32)) {
8        match token.kind {
9            TokenType::Number => {
10                if let Buffer::MultiByte(bs) = token.buf {
11                    if last_token_type == TokenType::CurlyOpen {
12                        fixed.push(b'"');
13                        fixed.extend(bs);
14                        fixed.push(b'"');
15                    } else if last_token_type == TokenType::Comma {
16                        fixed.push(b'"');
17                        fixed.extend(bs);
18                        fixed.push(b'"');
19                    } else {
20                        fixed.extend(bs);
21                    }
22                }
23            }
24            TokenType::String => {
25                if let Buffer::MultiByte(bs) = token.buf {
26                    fixed.extend(bs);
27                }
28            }
29            _ => {
30                fixed.extend_from_slice(token.kind.as_ref().as_bytes());
31            }
32        }
33        last_token_type = token.kind;
34    }
35    unsafe { String::from_utf8_unchecked(fixed) }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::fix;
41
42    #[test]
43    fn test_fix_json() {
44        let json = r#"{1: "foo", 2 : "bar"}"#;
45        let fixed = fix(json);
46        assert_eq!(fixed, r#"{"1":"foo","2":"bar"}"#);
47    }
48}