mini_json/
json.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use std::{collections::HashMap, fmt, fs};

use crate::parser::Parser;

#[derive(Debug)]
pub enum JsonValue {
    String(String),
    Integer(isize),
    Float(f64),
    Boolean(bool),
    Object(HashMap<String, JsonValue>),
    Array(Vec<JsonValue>),
}

#[derive(Debug)]
pub enum Json {
    Object(HashMap<String, JsonValue>),
    Array(Vec<JsonValue>),
}

pub fn parse_from_file(file_path: &str) -> std::io::Result<Json> {
    let source = fs::read_to_string(file_path)?;
    return Ok(parse_from_string(source));
}

pub fn parse_from_string(source: String) -> Json {
    let mut parser = Parser::new(source);
    return parser.parse();
}

fn print_value(depth: i32, json_value: &JsonValue, f: &mut fmt::Formatter) -> fmt::Result {
    match json_value {
        JsonValue::Boolean(val) => {
            write!(f, "{val}")?;
        }
        JsonValue::Float(val) => {
            write!(f, "{val}")?;
        }
        JsonValue::Integer(val) => {
            write!(f, "{val}")?;
        }
        JsonValue::String(val) => {
            write!(f, "\"{val}\"")?;
        }
        JsonValue::Array(array) => {
            writeln!(f, "[")?;

            for val in array {
                for _ in 0..depth {
                    write!(f, "  ")?;
                }

                print_value(depth + 1, val, f)?;

                writeln!(f, ",")?;
            }

            for _ in 0..depth - 1 {
                write!(f, "  ")?;
            }
            write!(f, "]")?;
        }
        JsonValue::Object(object) => {
            writeln!(f, "{{")?;

            for (key, val) in object {
                for _ in 0..depth {
                    write!(f, "  ")?;
                }
                write!(f, "\"{key}\": ")?;

                print_value(depth + 1, val, f)?;

                writeln!(f, ",")?;
            }

            for _ in 0..depth - 1 {
                write!(f, "  ")?;
            }
            write!(f, "}}")?;
        }
    }

    return Ok(());
}

impl fmt::Display for Json {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match &self {
            Json::Object(object) => {
                writeln!(f, "{{")?;

                for (key, val) in object {
                    write!(f, "  \"{key}\": ")?;
                    print_value(2, val, f)?;
                    writeln!(f, ",")?;
                }

                writeln!(f, "}}")?;
            }
            Json::Array(array) => {
                writeln!(f, "[")?;

                for val in array {
                    write!(f, "  ")?;
                    print_value(2, val, f)?;
                    writeln!(f, ",")?;
                }

                writeln!(f, "]")?;
            }
        }

        return Ok(());
    }
}