jjpwrgem_parse/format/
uglify.rs1use core::range::Range;
2
3use crate::{
4 Result,
5 ast::Document,
6 format::Emitter,
7 tokens::TokenStream,
8 traverse::{Visitor, parse_tokens, visit_document},
9};
10
11pub fn uglify_str(json: &str) -> Result<String> {
12 let mut buf = String::new();
13 uglify_str_into(&mut buf, json)?;
14 Ok(buf)
15}
16
17pub fn uglify_str_into(buf: &mut String, json: &str) -> Result<()> {
18 let mut visitor = UglifyEmitVisitor {
19 buf: std::mem::take(buf),
20 };
21 parse_tokens(&mut TokenStream::new(json), json, true, &mut visitor)?;
22 *buf = visitor.buf;
23 Ok(())
24}
25
26#[derive(Debug, Default)]
27pub(crate) struct UglifyEmitVisitor {
28 pub(crate) buf: String,
29}
30
31impl Emitter for UglifyEmitVisitor {
32 fn push(&mut self, c: char) {
33 self.buf.push(c);
34 }
35
36 fn push_str(&mut self, s: &str) {
37 self.buf.push_str(s);
38 }
39}
40
41impl<'a> Visitor<'a> for UglifyEmitVisitor {
42 fn on_object_open(&mut self, _range: Range<usize>) {
43 self.emit_object_open();
44 }
45
46 fn on_object_key(&mut self, _range: Range<usize>, key: &'a str) {
47 self.emit_string(key);
48 }
49
50 fn on_object_key_val_delim(&mut self) {
51 self.emit_key_val_delim();
52 }
53
54 fn on_object_close(&mut self, _range: Range<usize>) {
55 self.emit_object_close();
56 }
57
58 fn on_array_open(&mut self, _range: Range<usize>) {
59 self.emit_array_open();
60 }
61
62 fn on_array_close(&mut self, _range: Range<usize>) {
63 self.emit_array_close();
64 }
65
66 fn on_null(&mut self, _range: Range<usize>) {
67 self.emit_null();
68 }
69
70 fn on_string(&mut self, _range: Range<usize>, s: &'a str) {
71 self.emit_string(s);
72 }
73
74 fn on_mantissa(&mut self, _range: Range<usize>, mantissa: &'a str) {
75 self.emit_mantissa(mantissa);
76 }
77
78 fn on_exponent(&mut self, _range: Range<usize>, exponent: &'a str) {
79 self.emit_exponent(exponent);
80 }
81
82 fn on_boolean(&mut self, _range: Range<usize>, b: bool) {
83 self.emit_boolean(b);
84 }
85
86 fn on_item_delim(&mut self) {
87 self.emit_item_delim();
88 }
89}
90
91pub fn uglify_document<S: AsRef<str>>(doc: &Document<S>) -> String {
92 let mut visitor = UglifyEmitVisitor::default();
93 visit_document(doc, &mut visitor);
94 visitor.buf
95}
96
97pub fn uglify_document_into<S: AsRef<str>>(buf: &mut String, doc: &Document<S>) {
98 let mut visitor = UglifyEmitVisitor {
99 buf: std::mem::take(buf),
100 };
101 visit_document(doc, &mut visitor);
102 *buf = visitor.buf;
103}