Skip to main content

jjpwrgem_parse/format/
uglify.rs

1use 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}