1use std::cmp::Ordering;
9use std::mem;
10
11const MAX_DEPTH: usize = 500;
13
14struct InnerOptions<'a> {
15 width: i64,
18 prefix: &'a str,
21 indent: &'a str,
24 sort_keys: bool,
27}
28
29pub struct PrettyOptions<'a> {
30 inner: InnerOptions<'a>,
31}
32
33impl<'a> Default for PrettyOptions<'a> {
34 fn default() -> Self {
35 PrettyOptions {
36 inner: InnerOptions {
37 width: 80,
38 prefix: "",
39 indent: " ",
40 sort_keys: false,
41 },
42 }
43 }
44}
45
46impl<'a> PrettyOptions<'a> {
47 pub fn new() -> PrettyOptions<'a> {
48 PrettyOptions::default()
49 }
50 pub fn width(mut self, width: usize) -> Self {
51 self.inner.width = width as i64;
52 self
53 }
54 pub fn prefix(mut self, prefix: &'a str) -> Self {
55 self.inner.prefix = prefix;
56 self
57 }
58 pub fn indent(mut self, indent: &'a str) -> Self {
59 self.inner.indent = indent;
60 self
61 }
62 pub fn sort_keys(mut self, sort_keys: bool) -> Self {
63 self.inner.sort_keys = sort_keys;
64 self
65 }
66 pub fn pretty<J>(&self, json: J) -> String
67 where
68 J: AsRef<str>,
69 {
70 pretty_options(json, self)
71 }
72}
73
74pub fn pretty<J>(json: J) -> String
75where
76 J: AsRef<str>,
77{
78 PrettyOptions::default().pretty(json)
79}
80
81fn pretty_options<J>(json: J, opts: &PrettyOptions) -> String
82where
83 J: AsRef<str>,
84{
85 let json = json.as_ref().as_bytes();
86 let mut buf = Vec::with_capacity(json.len());
87 let prefix = opts.inner.prefix.as_bytes();
88 if prefix.len() != 0 {
89 buf.extend(prefix);
90 }
91 extend_pretty_any(
92 &mut buf,
93 json,
94 0,
95 true,
96 opts.inner.width,
97 prefix,
98 opts.inner.indent.as_bytes(),
99 opts.inner.sort_keys,
100 0,
101 0,
102 -1,
103 0,
104 );
105 if buf.len() > 0 {
106 buf.push(b'\n');
107 }
108 unsafe { mem::transmute::<Vec<u8>, String>(buf) }
109}
110
111fn extend_pretty_any(
112 buf: &mut Vec<u8>,
113 json: &[u8],
114 mut i: usize,
115 pretty: bool,
116 width: i64,
117 prefix: &[u8],
118 indent: &[u8],
119 sort_keys: bool,
120 tabs: i64,
121 nl: i64,
122 max: i64,
123 depth: usize,
124) -> (usize, i64, bool) {
125 while i < json.len() {
126 if json[i] <= b' ' {
127 i += 1;
128 continue;
129 }
130 if json[i] == b'"' {
131 return extend_pretty_string(buf, json, i, nl);
132 }
133 if (json[i] >= b'0' && json[i] <= b'9') || json[i] == b'-' {
134 return extend_pretty_number(buf, json, i, nl);
135 }
136 if json[i] == b'{' {
137 return extend_pretty_object(
138 buf,
139 json,
140 i,
141 b'{',
142 b'}',
143 pretty,
144 width,
145 prefix,
146 indent,
147 sort_keys,
148 tabs,
149 nl,
150 max,
151 depth + 1,
152 );
153 }
154 if json[i] == b'[' {
155 return extend_pretty_object(
156 buf,
157 json,
158 i,
159 b'[',
160 b']',
161 pretty,
162 width,
163 prefix,
164 indent,
165 sort_keys,
166 tabs,
167 nl,
168 max,
169 depth + 1,
170 );
171 }
172 match json[i] {
173 b't' => {
174 buf.extend("true".as_bytes());
175 return (i + 4, nl, true);
176 }
177 b'f' => {
178 buf.extend("false".as_bytes());
179 return (i + 5, nl, true);
180 }
181 b'n' => {
182 buf.extend("null".as_bytes());
183 return (i + 4, nl, true);
184 }
185 _ => {}
186 }
187 i += 1;
188 }
189 (i, nl, true)
190}
191
192fn extend_pretty_string(
193 buf: &mut Vec<u8>,
194 json: &[u8],
195 mut i: usize,
196 nl: i64,
197) -> (usize, i64, bool) {
198 let s = i;
199 i += 1;
200 while i < json.len() {
201 if json[i] == b'"' {
202 let mut sc = 0;
203 let mut j = i - 1;
204 while j > s {
205 if json[j] == b'\\' {
206 sc += 1;
207 } else {
208 break;
209 }
210 j -= 1;
211 }
212 if sc % 2 == 1 {
213 i += 1;
214 continue;
215 }
216 i += 1;
217 break;
218 }
219 i += 1;
220 }
221 buf.extend(&json[s..i]);
222 (i, nl, true)
223}
224
225fn extend_pretty_number(
226 buf: &mut Vec<u8>,
227 json: &[u8],
228 mut i: usize,
229 nl: i64,
230) -> (usize, i64, bool) {
231 let s = i;
232 i += 1;
233 while i < json.len() {
234 if json[i] <= b' '
235 || json[i] == b','
236 || json[i] == b':'
237 || json[i] == b']'
238 || json[i] == b'}'
239 {
240 break;
241 }
242 i += 1;
243 }
244 buf.extend(&json[s..i]);
245 (i, nl, true)
246}
247
248#[derive(Default)]
249struct Pair {
250 kstart: usize,
251 kend: usize,
252 vstart: usize,
253 vend: usize,
254}
255
256fn extend_pretty_object(
257 buf: &mut Vec<u8>,
258 json: &[u8],
259 mut i: usize,
260 open: u8,
261 close: u8,
262 pretty: bool,
263 width: i64,
264 prefix: &[u8],
265 indent: &[u8],
266 sort_keys: bool,
267 tabs: i64,
268 mut nl: i64,
269 max: i64,
270 depth: usize,
271) -> (usize, i64, bool) {
272 if depth == MAX_DEPTH {
273 let fragment = ugly(unsafe { std::str::from_utf8_unchecked(&json[i..]) });
274 buf.extend(fragment.as_bytes());
275 return (json.len(), nl, true);
276 }
277 let mut ok;
278 if width > 0 {
279 if pretty && open == b'[' && max == -1 {
280 let max = (width as i64) - ((buf.len() as i64) - nl);
282 if max > 3 {
283 let (s1, s2) = (buf.len(), i);
284 let res = extend_pretty_object(
285 buf,
286 json,
287 i,
288 b'[',
289 b']',
290 false,
291 width,
292 prefix,
293 "".as_bytes(),
294 sort_keys,
295 0,
296 0,
297 max,
298 depth,
299 );
300 i = res.0;
301 ok = res.2;
302 if ok && (buf.len() as i64) - (s1 as i64) <= max {
303 return (i, nl, true);
304 }
305 buf.truncate(s1);
306 i = s2;
307 }
308 } else if max != -1 && open == b'{' {
309 return (i, nl, false);
310 }
311 }
312 buf.push(open);
313 i += 1;
314 let mut pairs = Vec::new();
315 let mut n = 0;
316 while i < json.len() {
317 if json[i] <= b' ' {
318 i += 1;
319 continue;
320 }
321 if json[i] == close {
322 if pretty {
323 if open == b'{' && sort_keys {
324 sort_pairs(json, buf, &mut pairs);
325 }
326 if n > 0 {
327 nl = buf.len() as i64;
328 if buf[(nl - 1) as usize] != b' ' {
329 buf.push(b'\n');
330 }
331 }
332 if buf[buf.len() - 1] != open {
333 extend_tabs(buf, prefix, indent, tabs);
334 }
335 }
336 buf.push(close);
337 return (i + 1, nl, open != b'{');
338 }
339 if open == b'[' || json[i] == b'"' {
340 if n > 0 {
341 buf.push(b',');
342 if width != -1 && open == b'[' {
343 buf.push(b' ');
344 }
345 }
346 let mut p = Pair::default();
347 if pretty {
348 nl = buf.len() as i64;
349 if buf[(nl - 1) as usize] == b' ' {
350 buf[(nl - 1) as usize] = b'\n';
351 } else {
352 buf.push(b'\n');
353 }
354 if open == b'{' && sort_keys {
355 p.kstart = i;
356 p.vstart = buf.len();
357 }
358 extend_tabs(buf, prefix, indent, tabs + 1);
359 }
360 if open == b'{' {
361 let res = extend_pretty_string(buf, json, i, nl);
362 i = res.0;
363 nl = res.1;
364 if sort_keys {
365 p.kend = i;
366 }
367 buf.push(b':');
368 if pretty {
369 buf.push(b' ');
370 }
371 }
372 let r = extend_pretty_any(
373 buf,
374 json,
375 i,
376 pretty,
377 width,
378 prefix,
379 indent,
380 sort_keys,
381 tabs + 1,
382 nl,
383 max,
384 depth,
385 );
386 i = r.0;
387 nl = r.1;
388 ok = r.2;
389 if max != -1 && !ok {
390 return (i, nl, false);
391 }
392 if pretty && open == b'{' && sort_keys {
393 p.vend = buf.len();
394 if p.kstart <= p.kend && p.vstart <= p.vend {
395 pairs.push(p);
396 }
397 }
398 i -= 1;
399 n += 1;
400 }
401 i += 1;
402 }
403 (i, nl, open != b'{')
404}
405
406fn sort_pairs(json: &[u8], buf: &mut Vec<u8>, pairs: &mut Vec<Pair>) {
407 if pairs.len() == 0 {
408 return;
409 }
410 let vstart = pairs[0].vstart;
411 let vend = pairs[pairs.len() - 1].vend;
412 pairs.sort_by(|a, b| {
413 let key1 = &json[a.kstart + 1..a.kend - 1];
414 let key2 = &json[b.kstart + 1..b.kend - 1];
415 let cmp = key1.cmp(key2);
416 if cmp == Ordering::Equal {
417 a.vstart.cmp(&b.vstart)
418 } else {
419 cmp
420 }
421 });
422 let mut nbuf: Vec<u8> = Vec::with_capacity(vend - vstart);
423 for i in 0..pairs.len() {
424 let p = &pairs[i];
425 nbuf.extend(&buf[p.vstart..p.vend]);
426 if i < pairs.len() - 1 {
427 nbuf.push(b',');
428 nbuf.push(b'\n');
429 }
430 }
431 buf.truncate(vstart);
432 buf.extend(nbuf);
433}
434
435fn extend_tabs(buf: &mut Vec<u8>, prefix: &[u8], indent: &[u8], tabs: i64) {
436 if prefix.len() != 0 {
437 buf.extend(prefix);
438 }
439 for _ in 0..tabs {
440 buf.extend(indent);
441 }
442}
443
444pub fn ugly(json: &str) -> String {
445 let src = json.as_bytes();
446 let mut dst = Vec::with_capacity(json.len());
447 let mut i = 0;
448 while i < src.len() {
449 if src[i] > b' ' {
450 dst.push(src[i]);
451 if src[i] == b'"' {
452 i += 1;
453 while i < src.len() {
454 dst.push(src[i]);
455 if src[i] == b'"' {
456 let mut j = i - 1;
457 loop {
458 if src[j] != b'\\' {
459 break;
460 }
461 j -= 1;
462 }
463 if (i - j) % 2 != 0 {
464 break;
465 }
466 }
467 i += 1;
468 }
469 }
470 }
471 i += 1;
472 }
473 unsafe { mem::transmute::<Vec<u8>, String>(dst) }
474}
475
476#[cfg(test)]
477mod test {
478
479 const EXAMPLE_PRETTY: &str = r#"{
480 "name": {
481 "last": "Sanders",
482 "first": "Janet"
483 },
484 "children": ["Andy", "Carol", "Mike"],
485 "values": [
486 10.10,
487 true,
488 false,
489 null,
490 "hello",
491 {
492 "a": "b",
493 "c": "d"
494 },
495 []
496 ],
497 "values2": {},
498 "values3": [],
499 "deep": {
500 "deep": {
501 "deep": [1, 2, 3, 4, 5]
502 }
503 }
504}
505"#;
506 const EXAMPLE_UGLY: &str = r#"{"name":{"last":"Sanders","first":"Janet"},"children":["Andy","Carol","Mike"],"values":[10.10,true,false,null,"hello",{"a":"b","c":"d"},[]],"values2":{},"values3":[],"deep":{"deep":{"deep":[1,2,3,4,5]}}}"#;
507
508 #[test]
509 fn ugly() {
510 assert_eq!(super::ugly(EXAMPLE_PRETTY), EXAMPLE_UGLY);
511 assert_eq!(super::pretty(super::ugly(EXAMPLE_PRETTY)), EXAMPLE_PRETTY);
512 }
513 #[test]
514 fn pretty() {
515 assert_eq!(super::pretty(EXAMPLE_UGLY), EXAMPLE_PRETTY);
516 let res = super::PrettyOptions::new()
517 .prefix("\t")
518 .width(10)
519 .sort_keys(true)
520 .indent(" ")
521 .pretty(EXAMPLE_UGLY);
522 let expect = r#" {
523 "children": [
524 "Andy",
525 "Carol",
526 "Mike"
527 ],
528 "deep": {
529 "deep": {
530 "deep": [
531 1,
532 2,
533 3,
534 4,
535 5
536 ]
537 }
538 },
539 "name": {
540 "first": "Janet",
541 "last": "Sanders"
542 },
543 "values": [
544 10.10,
545 true,
546 false,
547 null,
548 "hello",
549 {
550 "a": "b",
551 "c": "d"
552 },
553 []
554 ],
555 "values2": {},
556 "values3": []
557 }
558"#;
559 assert_eq!(res, expect);
560 }
561
562 #[test]
563 fn xcover() {
564 let res = super::ugly(
565 &super::PrettyOptions::new()
566 .sort_keys(true)
567 .pretty(r#"{"hello":"JELLO","hello":"HELLO"}"#),
568 );
569 assert_eq!(res, r#"{"hello":"JELLO","hello":"HELLO"}"#);
570 super::PrettyOptions::new()
571 .sort_keys(true)
572 .pretty(r#"{"hello":"JELLO","hello":"HELLO"}"#);
573
574 super::pretty(r#"{"#);
575 super::pretty(r#"r"#);
576 }
577
578 #[test]
579 fn depth() {
580 const JSON: &str = r#"
581 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
582 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
583 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
584 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
585 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
586 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
587 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
588 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
589 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
590 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
591 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
592 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
593 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
594 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
595 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
596 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
597 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
598 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
599 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
600 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
601 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
602 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
603 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
604 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
605 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
606 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
607 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
608 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
609 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
610 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
611 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
612 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
613 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
614 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
615 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
616 [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
617 "hello", "jello", {"hello": "jello"}, true, false, null, 0.0
618 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
619 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
620 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
621 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
622 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
623 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
624 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
625 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
626 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
627 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
628 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
629 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
630 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
631 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
632 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
633 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
634 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
635 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
636 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
637 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
638 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
639 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
640 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
641 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
642 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
643 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
644 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
645 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
646 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
647 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
648 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
649 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
650 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
651 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
652 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
653 ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
654 "#;
655
656 println!("{}", super::pretty(JSON));
657 }
658}