1use std::collections::HashMap;
2
3use crate::error::ParseError;
4use crate::tokenizer::TokenKind;
5use crate::{parse::Parse, token_stream::TokenStream, tokenizer::Tokenizer};
6
7#[derive(Debug, Clone, PartialEq)]
8pub enum JsonElement {
9 Number(f64),
10 String(String),
11 Boolean(bool),
12 Array(Vec<JsonElement>),
13 Object(HashMap<String, JsonElement>),
14 Null,
15}
16
17pub struct Json {
18 pub root: JsonElement,
19}
20
21impl Json {
22 fn parse_tokens(mut tokens: TokenStream) -> Result<JsonElement, ParseError> {
23 fn parse_value(tokens: &mut TokenStream) -> Result<JsonElement, ParseError> {
24 use TokenKind::*;
25
26 let tk = tokens.current();
27
28 match tk.kind {
29 String => {
30 let t = tokens.advance();
31 Ok(JsonElement::String(t.lexeme))
32 }
33 Number => {
34 let t = tokens.advance();
35 let n = t
36 .lexeme
37 .parse::<f64>()
38 .map_err(|_e| ParseError::new(format!("Invalid number '{}'", t.lexeme)))?;
39 Ok(JsonElement::Number(n))
40 }
41 Boolean => {
42 let t = tokens.advance();
43 let b = match t.lexeme.as_str() {
44 "true" => true,
45 "false" => false,
46 other => {
47 return Err(ParseError::new(format!(
48 "Invalid boolean literal '{}'",
49 other
50 )));
51 }
52 };
53 Ok(JsonElement::Boolean(b))
54 }
55 Null => {
56 tokens.advance();
57 Ok(JsonElement::Null)
58 }
59 LeftBrace => parse_object(tokens),
60 LeftBracket => parse_array(tokens),
61 _ => Err(ParseError::new(format!("Unexpected token: {:?}", tk.kind))),
62 }
63 }
64
65 fn parse_object(tokens: &mut TokenStream) -> Result<JsonElement, ParseError> {
66 use TokenKind::*;
67
68 let start = tokens.current();
69 if start.kind != LeftBrace {
70 return Err(ParseError::new("Expected '{' at start of object"));
71 }
72 tokens.advance();
73
74 let mut map = HashMap::new();
75
76 if tokens.current().kind == RightBrace {
77 tokens.advance();
78 return Ok(JsonElement::Object(map));
79 }
80
81 loop {
82 let key_token = tokens.current();
83 if key_token.kind != String {
84 return Err(ParseError::new(format!(
85 "Expected string key in object, found {:?}",
86 key_token.kind
87 )));
88 }
89 let key = tokens.advance().lexeme;
90
91 if tokens.current().kind != Colon {
92 return Err(ParseError::new("Expected ':' after object key"));
93 }
94 tokens.advance();
95
96 let value = parse_value(tokens)?;
97 map.insert(key, value);
98
99 match tokens.current().kind {
100 Comma => {
101 tokens.advance();
102 continue;
103 }
104 RightBrace => {
105 tokens.advance();
106 break;
107 }
108 other => {
109 return Err(ParseError::new(format!(
110 "Expected ',' or '}}' in object, found {:?}",
111 other
112 )));
113 }
114 }
115 }
116
117 Ok(JsonElement::Object(map))
118 }
119
120 fn parse_array(tokens: &mut TokenStream) -> Result<JsonElement, ParseError> {
121 use TokenKind::*;
122
123 let start = tokens.current();
124 if start.kind != LeftBracket {
125 return Err(ParseError::new("Expected '[' at start of array"));
126 }
127 tokens.advance();
128
129 let mut items = Vec::new();
130
131 if tokens.current().kind == RightBracket {
132 tokens.advance();
133 return Ok(JsonElement::Array(items));
134 }
135
136 loop {
137 let value = parse_value(tokens)?;
138 items.push(value);
139
140 match tokens.current().kind {
141 Comma => {
142 tokens.advance();
143 continue;
144 }
145 RightBracket => {
146 tokens.advance();
147 break;
148 }
149 other => {
150 return Err(ParseError::new(format!(
151 "Expected ',' or ']' in array, found {:?}",
152 other
153 )));
154 }
155 }
156 }
157
158 Ok(JsonElement::Array(items))
159 }
160
161 let value = parse_value(&mut tokens)?;
162 Ok(value)
163 }
164
165 fn _parse(source: impl Into<String>) -> Result<Self, ParseError> {
166 let mut tokenizer = Tokenizer::new(source.into());
167 let tokens = tokenizer.scan_tokens()?;
168 let root = Self::parse_tokens(tokens)?;
169
170 Ok(Json { root })
171 }
172}
173
174impl Parse for Json {
175 fn parse(source: impl Into<String>) -> Result<Self, ParseError>
176 where
177 Self: Sized,
178 {
179 Self::_parse(source)
180 }
181}