1use std::collections::HashMap;
2use std::fs::File;
3
4use crate::scanner::{Scanner, Token, TokenKind};
5use crate::value::{JSONError, JSONValue};
6
7#[derive(Debug)]
8pub struct Parser<'a> {
9 scanner: Scanner<'a>,
10 ct: Token,
11}
12
13impl<'a> Parser<'a> {
14 pub fn from_string(data: &'a String) -> Self {
15 Parser {
16 scanner: Scanner::from_string(&data),
17 ct: Token::dummy(),
18 }
19 }
20
21 pub fn from_file(file: File) -> Self {
22 Parser {
23 scanner: Scanner::from_file(file),
24 ct: Token::dummy(),
25 }
26 }
27
28 pub fn parse(&mut self) -> Result<JSONValue, JSONError> {
29 let mut value = Err(JSONError::new("Empty json stream".to_string(), 0, 0));
30 loop {
31 let tk = self.consume();
32 value = match tk.kind {
33 TokenKind::Eof => break,
34 _ => self.parse_value(),
35 }
36 }
37 value
38 }
39
40 fn consume(&mut self) -> Token {
41 self.ct = self.scanner.next_token();
42 self.ct.clone()
43 }
44
45 fn parse_object(&mut self) -> Result<JSONValue, JSONError> {
46 let mut values: HashMap<String, JSONValue> = HashMap::new();
47
48 self.consume();
50 if self.ct.kind == TokenKind::RightBrace {
51 self.consume();
52 return Ok(JSONValue::Object(values));
53 }
54
55 while self.ct.kind != TokenKind::RightBrace && self.ct.kind != TokenKind::Eof {
56 if self.ct.kind != TokenKind::String {
57 return Err(JSONError::new(
58 format!("Expecting key name but found {:?}", self.ct.kind),
59 self.ct.line,
60 self.ct.col,
61 ));
62 }
63 let key = self.ct.value.clone();
64 self.consume(); if self.ct.kind != TokenKind::Collon {
67 return Err(JSONError::new(
68 format!("Expecting collon but found {:?}", self.ct.kind),
69 self.ct.line,
70 self.ct.col,
71 ));
72 }
73 self.consume(); let r = self.parse_value();
76 match r {
77 Ok(v) => values.insert(key, v),
78 Err(_) => return r,
79 };
80
81 match self.ct.kind {
82 TokenKind::Comma => {
83 self.consume();
84 if self.ct.kind == TokenKind::RightBrace {
85 return Err(JSONError::new(
86 format!("Trailing `{}`", self.ct.value),
87 self.ct.line,
88 self.ct.col,
89 ));
90 }
91 }
92 TokenKind::RightBrace => {
93 self.consume();
94 return Ok(JSONValue::Object(values));
95 }
96 _ => {
97 return Err(JSONError::new(
98 format!("Unexpected token {}", self.ct.value),
99 self.ct.line,
100 self.ct.col,
101 ))
102 }
103 };
104 }
105
106 Ok(JSONValue::Object(values))
107 }
108
109 fn parse_array(&mut self) -> Result<JSONValue, JSONError> {
110 let mut values: Vec<JSONValue> = Vec::new();
111
112 self.consume();
114 if self.ct.kind == TokenKind::RightBracket {
115 self.consume();
116 return Ok(JSONValue::Array(values));
117 }
118
119 while self.ct.kind != TokenKind::RightBracket && self.ct.kind != TokenKind::Eof {
120 let rst = self.parse_value();
121 match rst {
122 Ok(v) => values.push(v),
123 Err(err) => return Err(err),
124 }
125
126 match self.ct.kind {
127 TokenKind::Comma => {
128 self.consume();
129 if self.ct.kind == TokenKind::RightBracket {
130 return Err(JSONError::new(
131 format!("Trailing `{}`", self.ct.value),
132 self.ct.line,
133 self.ct.col,
134 ));
135 }
136 }
137 TokenKind::RightBracket => {
138 self.consume();
139 return Ok(JSONValue::Array(values));
140 }
141 _ => {
142 return Err(JSONError::new(
143 format!("Unexpected token {}", self.ct.value),
144 self.ct.line,
145 self.ct.col,
146 ))
147 }
148 };
149 }
150
151 Ok(JSONValue::Array(values))
152 }
153
154 fn parse_value(&mut self) -> Result<JSONValue, JSONError> {
155 let ct = &self.ct;
156 let value = match ct.kind {
157 TokenKind::Null => {
158 self.consume();
159 Ok(JSONValue::Null)
160 }
161 TokenKind::False => {
162 self.consume();
163 Ok(JSONValue::Boolean(false))
164 }
165 TokenKind::True => {
166 self.consume();
167 Ok(JSONValue::Boolean(true))
168 }
169 TokenKind::String => {
170 let v = ct.value.clone();
171 self.consume();
172 Ok(JSONValue::String(v))
173 }
174 TokenKind::Number => {
175 match ct.value.parse::<f64>() {
177 Ok(n) => {
178 self.consume();
179 Ok(JSONValue::Number(n))
180 }
181 Err(_) => Err(JSONError::new(
182 format!("{} is NaN ", ct.value),
183 ct.line,
184 ct.col,
185 )),
186 }
187 }
188 TokenKind::LeftBrace => self.parse_object(),
189 TokenKind::LeftBracket => self.parse_array(),
190 _ => {
191 return Err(JSONError::new(
192 format!("Unexpected token {}", ct.value),
193 ct.line,
194 ct.col,
195 ))
196 }
197 };
198
199 value
204 }
205}
206
207#[cfg(test)]
208mod tests {
209
210 #[test]
211 fn test_basic_parsing() {
212 }
214
215 #[test]
216 fn complex_parsing() {
217 }
219}