streamdal_gjson/
pretty.rs

1// Copyright 2021 Joshua J Baker. All rights reserved.
2// Use of this source code is governed by an MIT-style
3// license that can be found in the LICENSE file.
4
5// Bit flags passed to the "info" parameter of the iter function which
6// provides additional information about the data
7
8use std::cmp::Ordering;
9use std::mem;
10
11// maxDepth is maximum number of nested objects and arrays
12const MAX_DEPTH: usize = 500;
13
14struct InnerOptions<'a> {
15    // Width is an max column width for single line arrays
16    // Default is 80
17    width: i64,
18    // Prefix is a prefix for all lines
19    // Default is an empty string
20    prefix: &'a str,
21    // Indent is the nested indentation
22    // Default is two spaces
23    indent: &'a str,
24    // sort_keys will sort the keys alphabetically
25    // Default is false
26    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            // here we try to create a single line array
281            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}