1use crate::value::Value;
10use std::collections::BTreeMap;
11
12pub fn parse_json_value(text: &str) -> Option<Value> {
16 JsonReader::new(text).parse_whole()
17}
18
19struct JsonReader {
22 chars: Vec<char>,
23 i: usize,
24}
25
26impl JsonReader {
27 fn new(text: &str) -> JsonReader {
28 JsonReader {
29 chars: text.chars().collect(),
30 i: 0,
31 }
32 }
33
34 fn parse_whole(&mut self) -> Option<Value> {
35 let v = self.value()?;
36 self.skip_ws();
37 if self.i != self.chars.len() {
38 return None;
39 }
40 Some(v)
41 }
42
43 fn value(&mut self) -> Option<Value> {
44 self.skip_ws();
45 match self.peek()? {
46 '{' => self.object(),
47 '[' => self.array(),
48 '"' => self.string().map(Value::String),
49 't' | 'f' => self.boolean(),
50 'n' => self.null(),
51 _ => self.number(),
52 }
53 }
54
55 fn object(&mut self) -> Option<Value> {
56 self.expect('{')?;
57 let mut map = BTreeMap::new();
58 self.skip_ws();
59 if self.peek()? == '}' {
60 self.i += 1;
61 return Some(Value::Map(map));
62 }
63 loop {
64 self.skip_ws();
65 let key = self.string()?;
66 self.skip_ws();
67 self.expect(':')?;
68 map.insert(key, self.value()?);
69 self.skip_ws();
70 match self.next()? {
71 '}' => return Some(Value::Map(map)),
72 ',' => {}
73 _ => return None,
74 }
75 }
76 }
77
78 fn array(&mut self) -> Option<Value> {
79 self.expect('[')?;
80 let mut list = Vec::new();
81 self.skip_ws();
82 if self.peek()? == ']' {
83 self.i += 1;
84 return Some(Value::List(list));
85 }
86 loop {
87 list.push(self.value()?);
88 self.skip_ws();
89 match self.next()? {
90 ']' => return Some(Value::List(list)),
91 ',' => {}
92 _ => return None,
93 }
94 }
95 }
96
97 fn string(&mut self) -> Option<String> {
98 self.expect('"')?;
99 let mut out = String::new();
100 loop {
101 match self.next()? {
102 '"' => return Some(out),
103 '\\' => match self.next()? {
104 '"' => out.push('"'),
105 '\\' => out.push('\\'),
106 '/' => out.push('/'),
107 'n' => out.push('\n'),
108 'r' => out.push('\r'),
109 't' => out.push('\t'),
110 'b' => out.push('\u{0008}'),
111 'f' => out.push('\u{000c}'),
112 'u' => {
113 let code = self.hex4()?;
114 out.push(char::from_u32(code)?);
115 }
116 _ => return None,
117 },
118 c => out.push(c),
119 }
120 }
121 }
122
123 fn hex4(&mut self) -> Option<u32> {
124 if self.i + 4 > self.chars.len() {
125 return None;
126 }
127 let slice: String = self.chars[self.i..self.i + 4].iter().collect();
128 self.i += 4;
129 u32::from_str_radix(&slice, 16).ok()
130 }
131
132 fn number(&mut self) -> Option<Value> {
133 let start = self.i;
134 while self.i < self.chars.len() && "-+.eE0123456789".contains(self.chars[self.i]) {
135 self.i += 1;
136 }
137 if self.i == start {
138 return None;
139 }
140 let num: String = self.chars[start..self.i].iter().collect();
141 if num.contains(['.', 'e', 'E']) {
142 num.parse::<f64>().ok().map(Value::Float)
143 } else {
144 num.parse::<i64>().ok().map(Value::Int)
145 }
146 }
147
148 fn boolean(&mut self) -> Option<Value> {
149 if self.starts_with("true") {
150 self.i += 4;
151 Some(Value::Bool(true))
152 } else if self.starts_with("false") {
153 self.i += 5;
154 Some(Value::Bool(false))
155 } else {
156 None
157 }
158 }
159
160 fn null(&mut self) -> Option<Value> {
161 if self.starts_with("null") {
162 self.i += 4;
163 Some(Value::Null)
164 } else {
165 None
166 }
167 }
168
169 fn starts_with(&self, lit: &str) -> bool {
170 let lit: Vec<char> = lit.chars().collect();
171 self.i + lit.len() <= self.chars.len() && self.chars[self.i..self.i + lit.len()] == lit[..]
172 }
173
174 fn skip_ws(&mut self) {
175 while self.i < self.chars.len() && matches!(self.chars[self.i], ' ' | '\n' | '\r' | '\t') {
176 self.i += 1;
177 }
178 }
179
180 fn peek(&self) -> Option<char> {
181 self.chars.get(self.i).copied()
182 }
183
184 fn next(&mut self) -> Option<char> {
185 let c = self.chars.get(self.i).copied()?;
186 self.i += 1;
187 Some(c)
188 }
189
190 fn expect(&mut self, c: char) -> Option<()> {
191 if self.next()? == c { Some(()) } else { None }
192 }
193}