1use std::collections::HashMap;
2
3pub fn fix(input: impl Into<String>) -> String {
10 let json = Parser::new(input).parse_and_fix();
11 json.deserialize_all().stringify(0)
12}
13
14struct Parser {
15 chars: Vec<char>,
16 i: usize,
17}
18
19impl Parser {
20 pub fn new(input: impl Into<String>) -> Self {
21 Self {
22 chars: input.into().trim().chars().collect(),
23 i: 0,
24 }
25 }
26
27 fn peek(&mut self) -> Option<char> {
28 self.chars.get(self.i).copied()
29 }
30
31 fn next(&mut self) -> Option<char> {
32 let c = self.peek();
33 if c.is_some() {
34 self.i += 1;
35 }
36 c
37 }
38
39 fn skip_whitespace(&mut self) {
40 while let Some(c) = self.peek()
41 && c.is_whitespace()
42 {
43 self.next();
44 }
45 }
46
47 pub fn parse_and_fix(&mut self) -> Json {
48 self.parse_value()
49 }
50
51 fn parse_value(&mut self) -> Json {
52 self.skip_whitespace();
53
54 if let Some(c) = self.peek() {
55 match c {
56 'n' | 'N' | 't' | 'T' | 'f' | 'F' => self.parse_static(),
57
58 val if val.is_ascii_digit() || val == '-' || val == '.' => self.parse_number(),
59
60 '"' => self.parse_string(),
61
62 '[' => self.parse_array(),
63
64 '{' => self.parse_object(),
65
66 _ => {
67 self.next();
68 Json::Null
69 }
70 }
71 } else {
72 Json::Null
73 }
74 }
75
76 fn parse_static(&mut self) -> Json {
77 match self.next().unwrap().to_ascii_lowercase() {
78 'n' => Json::Null,
79 't' => Json::True,
80 _ => Json::False,
81 }
82 }
83
84 fn parse_number(&mut self) -> Json {
85 let mut lex = String::new();
86
87 if let Some('-') = self.peek() {
88 lex.push('-');
89 self.next();
90
91 while let Some('-') = self.peek() {
92 self.next();
93 }
94 }
95
96 if let Some('.') = self.peek() {
97 lex.push('0');
98 }
99
100 if let Some('0') = self.peek() {
102 lex.push('0');
103 self.next();
104
105 while let Some(c) = self.peek() {
106 if c == '0' {
107 self.next();
108 } else {
109 if c.is_ascii_digit() {
110 lex.pop();
111 }
112 break;
113 }
114 }
115 }
116
117 while let Some(c) = self.peek()
119 && c.is_ascii_digit()
120 {
121 lex.push(c);
122 self.next();
123 }
124
125 if let Some('.') = self.peek() {
127 lex.push('.');
128 self.next();
129
130 let mut count = 0;
131 while let Some(c) = self.peek()
132 && c.is_ascii_digit()
133 {
134 lex.push(c);
135 self.next();
136 count += 1;
137 }
138
139 if count == 0 {
140 lex.push('0');
141 }
142 }
143
144 if let Some(c) = self.peek()
146 && (c == 'e' || c == 'E')
147 {
148 lex.push(c);
149 self.next();
150
151 if let Some(sign) = self.peek()
152 && (sign == '-' || sign == '+')
153 {
154 lex.push(sign);
155 self.next();
156 }
157
158 let mut count = 0;
159 while let Some(c) = self.peek()
160 && c.is_ascii_digit()
161 {
162 lex.push(c);
163 self.next();
164 count += 1;
165 }
166
167 if count == 0 {
168 if lex.ends_with('-') || lex.ends_with('+') {
169 lex.pop();
170 }
171 lex.pop();
172 }
173 }
174
175 if lex == "-" {
176 lex.push('0');
177 }
178
179 Json::Number(lex)
180 }
181
182 fn parse_string(&mut self) -> Json {
183 let mut lex = String::new();
184
185 self.next();
186 while let Some(c) = self.next() {
187 match c {
188 '"' => {
189 break;
190 }
191
192 '\\' => {
193 if let Some(esc) = self.next() {
194 match esc {
195 '"' => lex.push('"'),
196 '\\' => lex.push('\\'),
197 '/' => lex.push('/'),
198 'b' => lex.push('\u{0008}'),
199 'f' => lex.push('\u{000C}'),
200 'n' => lex.push('\n'),
201 'r' => lex.push('\r'),
202 't' => lex.push('\t'),
203
204 'u' => {
205 if let Some(c) = self.parse_unicode_escape() {
206 lex.push(c);
207 }
208 }
209
210 ch => {
211 lex.push(ch);
212 }
213 }
214 }
215 }
216
217 _ => {
218 lex.push(c);
219 }
220 }
221 }
222
223 Json::String(lex)
224 }
225
226 fn parse_unicode_escape(&mut self) -> Option<char> {
227 let mut hex = String::new();
228 for _ in 0..4 {
229 if let Some(c) = self.next() {
230 hex.push(c);
231 } else {
232 return None;
233 }
234 }
235
236 let code = u32::from_str_radix(&hex, 16).ok()?;
237
238 if let Some(ch) = char::from_u32(code) {
239 Some(ch)
240 } else if (0xD800..=0xDBFF).contains(&code) {
241 if let (Some('\\'), Some('u')) = (self.next(), self.next()) {
242 let mut low_hex = String::new();
243 for _ in 0..4 {
244 if let Some(c) = self.next() {
245 low_hex.push(c);
246 } else {
247 return None;
248 }
249 }
250
251 let low_code = u32::from_str_radix(&low_hex, 16).ok()?;
252
253 if (0xDC00..=0xDFFF).contains(&low_code) {
254 let full_code = 0x10000 + ((code - 0xD800) << 10) + (low_code - 0xDC00);
255
256 char::from_u32(full_code)
257 } else {
258 None
259 }
260 } else {
261 None
262 }
263 } else {
264 None
265 }
266 }
267
268 fn parse_array(&mut self) -> Json {
269 let mut arr = Vec::new();
270
271 self.next();
272
273 loop {
274 self.skip_whitespace();
275
276 match self.peek() {
277 Some(']') => {
278 self.next();
279 break;
280 }
281
282 Some(',') => {
283 self.next();
284 continue;
285 }
286
287 Some(_) => {
288 arr.push(self.parse_value());
289
290 self.skip_whitespace();
291
292 while let Some(c) = self.peek() {
293 match c {
294 ']' | ',' => {
295 break;
296 }
297
298 _ => {
299 self.next();
300 }
301 }
302 }
303 }
304
305 None => {
306 break;
307 }
308 }
309 }
310
311 Json::Array(arr)
312 }
313
314 fn parse_object(&mut self) -> Json {
315 let mut obj = HashMap::new();
316 let mut order = Vec::new();
317
318 self.next();
319
320 loop {
321 self.skip_whitespace();
322
323 match self.peek() {
324 Some('}') => {
325 self.next();
326 break;
327 }
328
329 Some('"') => {
330 let key = match self.parse_string() {
331 Json::String(s) => s,
332 _ => unreachable!(),
333 };
334
335 self.skip_whitespace();
336
337 if self.peek() == Some(':') {
338 self.next();
339 }
340
341 if obj.contains_key(&key)
342 && let Some(pos) = order.iter().position(|k| k == &key)
343 {
344 order.remove(pos);
345 }
346
347 obj.insert(key.clone(), self.parse_value());
348 order.push(key);
349 }
350
351 None => {
352 break;
353 }
354
355 _ => {
356 self.next();
357 }
358 }
359 }
360
361 Json::Object((obj, order))
362 }
363}
364
365enum Json {
366 Null,
367 True,
368 False,
369 Number(String),
370 String(String),
371 Array(Vec<Json>),
372 Object((HashMap<String, Json>, Vec<String>)),
373}
374
375impl Json {
376 pub fn deserialize_all(self) -> Json {
377 match self {
378 Self::String(val) => {
379 let trimmed = val.trim();
380
381 if trimmed.starts_with('{') || trimmed.starts_with('[') {
382 Parser::new(trimmed).parse_and_fix().deserialize_all()
383 } else {
384 Json::String(val)
385 }
386 }
387
388 Json::Array(arr) => Json::Array(arr.into_iter().map(|v| v.deserialize_all()).collect()),
389
390 Json::Object((obj, order)) => Json::Object((
391 obj.into_iter()
392 .map(|(k, v)| (k, v.deserialize_all()))
393 .collect(),
394 order,
395 )),
396
397 other => other,
398 }
399 }
400
401 pub fn stringify(&self, tabs: usize) -> String {
402 const TAB: &str = " ";
403
404 match self {
405 Self::Null => "null".to_string(),
406 Self::True => "true".to_string(),
407 Self::False => "false".to_string(),
408
409 Self::Number(val) => val.clone(),
410 Self::String(val) => format!("\"{}\"", val),
411
412 Self::Array(arr) => {
413 if arr.is_empty() {
414 return "[]".to_string();
415 }
416
417 let mut result = String::from("[\n");
418 let tab_str = TAB.repeat(tabs + 1);
419
420 for val in arr {
421 result.push_str(&format!("{}{},\n", tab_str, val.stringify(tabs + 1)));
422 }
423
424 result.truncate(result.len() - 2);
425
426 result.push('\n');
427 result.push_str(&TAB.repeat(tabs));
428 result.push(']');
429 result
430 }
431
432 Self::Object((obj, order)) => {
433 if obj.is_empty() {
434 return "{}".to_string();
435 }
436
437 let mut result = String::from("{\n");
438 let tab_str = TAB.repeat(tabs + 1);
439
440 for key in order {
441 if let Some(val) = obj.get(key) {
442 result.push_str(&format!(
443 "{}\"{}\": {},\n",
444 tab_str,
445 key,
446 val.stringify(tabs + 1)
447 ));
448 }
449 }
450
451 result.truncate(result.len() - 2);
452
453 result.push('\n');
454 result.push_str(&TAB.repeat(tabs));
455 result.push('}');
456 result
457 }
458 }
459 }
460
461 fn _stringify_without_formatting(&self) -> String {
462 match self {
463 Self::Null => "null".to_string(),
464 Self::True => "true".to_string(),
465 Self::False => "false".to_string(),
466
467 Self::Number(val) => val.clone(),
468 Self::String(val) => format!("\"{}\"", val),
469
470 Self::Array(arr) => {
471 let mut result = String::from('[');
472
473 for val in arr {
474 result.push_str(&format!("{},", val._stringify_without_formatting()));
475 }
476
477 if result.ends_with(',') {
478 result.pop();
479 }
480
481 result.push(']');
482 result
483 }
484
485 Self::Object((obj, order)) => {
486 let mut result = String::from('{');
487
488 for key in order {
489 if let Some(val) = obj.get(key) {
490 result.push_str(&format!(
491 "\"{}\":{},",
492 key,
493 val._stringify_without_formatting()
494 ));
495 }
496 }
497
498 if result.ends_with(',') {
499 result.pop();
500 }
501
502 result.push('}');
503 result
504 }
505 }
506 }
507}
508
509fn _fix_without_formatting(input: impl Into<String>) -> String {
510 let json = Parser::new(input).parse_and_fix();
511 json.deserialize_all()._stringify_without_formatting()
512}
513
514#[cfg(test)]
515mod tests;