json_pretty_compact/
fmt.rs1use serde_json::ser::{CharEscape, CompactFormatter, Formatter};
24use std::io;
25
26use crate::error::Error;
27use crate::options::Options;
28use crate::token::Token;
29
30fn write_to_vec<F: FnOnce(&mut Vec<u8>) -> io::Result<()>>(f: F) -> io::Result<Vec<u8>> {
31 let mut vec = vec![];
32
33 f(&mut vec).map(|()| vec)
34}
35
36macro_rules! write_func {
37 ($name:ident ( )) => {
38 fn $name<W: ?Sized + io::Write>(&mut self, writer: &mut W) -> io::Result<()> {
39 let vec = write_to_vec(|v| CompactFormatter.$name(v))?;
40
41 self.token.push(Token::Data(vec.into()));
42 self.format_json(writer)
43 }
44 };
45
46 ($name:ident ( $value:ty ) ) => {
47 fn $name<W: ?Sized + io::Write>(
48 &mut self,
49 writer: &mut W,
50 value: $value,
51 ) -> io::Result<()> {
52 let vec = write_to_vec(|v| CompactFormatter.$name(v, value))?;
53
54 self.token.push(Token::Data(vec.into()));
55 self.format_json(writer)
56 }
57 };
58}
59
60pub struct PrettyCompactFormatter {
99 options: Options,
100 token: Vec<Token>,
101 level: u32,
102}
103
104impl PrettyCompactFormatter {
105 pub fn new() -> PrettyCompactFormatter {
107 Self {
108 options: Options::default(),
109 token: vec![],
110 level: 0,
111 }
112 }
113
114 pub fn no_rules() -> PrettyCompactFormatter {
116 Self {
117 options: Options::no_rules(),
118 ..Self::new()
119 }
120 }
121
122 pub fn with_indent(mut self, indent: u32) -> Self {
124 self.options.set_indent(indent);
125 self
126 }
127
128 pub fn with_max_line_length(mut self, len: u32) -> Self {
130 self.options.set_max_len(len);
131 self
132 }
133
134 fn format_json<W: ?Sized + io::Write>(&mut self, writer: &mut W) -> io::Result<()> {
135 if self.token.last().map_or(false, |t| t.is_end_array()) {
136 self.reduce_array()?;
137 } else if self.token.last().map_or(false, |t| t.is_end_object()) {
138 self.reduce_object()?;
139 }
140
141 if self.token.len() == 1 {
142 self.token[0].format(writer, &self.options, None)?;
143 }
144
145 Ok(())
146 }
147
148 fn reduce_array(&mut self) -> Result<(), Error> {
149 let (idx, level) = self
150 .find_last_token(|t| t.as_begin_array())
151 .ok_or(Error::NoArrayStart)?;
152
153 let mut array = self.token.drain(idx..).collect::<Vec<Token>>();
154
155 array.remove(0);
156 array.pop();
157
158 self.token.push(Token::Array(level, array));
159
160 Ok(())
161 }
162
163 fn reduce_object(&mut self) -> Result<(), Error> {
164 let (idx, level) = self
165 .find_last_token(|t| t.as_begin_object())
166 .ok_or(Error::NoObjectStart)?;
167
168 let mut object = self.token.drain(idx..).collect::<Vec<Token>>();
169
170 object.remove(0);
171 object.pop();
172
173 self.token.push(Token::Object(level, object));
174
175 Ok(())
176 }
177
178 fn find_last_token<P: FnMut(&Token) -> Option<u32>>(
179 &self,
180 mut predicate: P,
181 ) -> Option<(usize, u32)> {
182 self.token
183 .iter()
184 .enumerate()
185 .rev()
186 .find_map(|(idx, ev)| predicate(ev).map(|n| (idx, n)))
187 }
188}
189
190impl Default for PrettyCompactFormatter {
191 fn default() -> Self {
192 Self::new()
193 }
194}
195
196impl Formatter for PrettyCompactFormatter {
197 write_func!(write_null());
198 write_func!(write_bool(bool));
199 write_func!(write_i8(i8));
200 write_func!(write_i16(i16));
201 write_func!(write_i32(i32));
202 write_func!(write_i64(i64));
203 write_func!(write_i128(i128));
204 write_func!(write_u8(u8));
205 write_func!(write_u16(u16));
206 write_func!(write_u32(u32));
207 write_func!(write_u64(u64));
208 write_func!(write_u128(u128));
209 write_func!(write_f32(f32));
210 write_func!(write_f64(f64));
211 write_func!(write_number_str(&str));
212
213 fn begin_string<W: ?Sized + io::Write>(&mut self, _writer: &mut W) -> io::Result<()> {
214 self.token.push(Token::Data(b"\"".to_vec()));
215
216 Ok(())
217 }
218
219 fn end_string<W: ?Sized + io::Write>(&mut self, writer: &mut W) -> io::Result<()> {
220 let t = self.token.last_mut().ok_or(Error::EmptyTokenQueue)?;
221 let data = t.as_data_mut_err()?;
222
223 data.extend_from_slice(b"\"");
224
225 self.format_json(writer)
226 }
227
228 fn write_string_fragment<W: ?Sized + io::Write>(
229 &mut self,
230 _writer: &mut W,
231 fragment: &str,
232 ) -> io::Result<()> {
233 let t = self.token.last_mut().ok_or(Error::EmptyTokenQueue)?;
234 let data = t.as_data_mut_err()?;
235
236 data.extend_from_slice(fragment.as_bytes());
237
238 Ok(())
239 }
240
241 fn write_char_escape<W: ?Sized + io::Write>(
242 &mut self,
243 _writer: &mut W,
244 char_escape: CharEscape,
245 ) -> io::Result<()> {
246 let vec = write_to_vec(|v| CompactFormatter.write_char_escape(v, char_escape))?;
247
248 let t = self.token.last_mut().ok_or(Error::EmptyTokenQueue)?;
249 let data = t.as_data_mut_err()?;
250
251 data.extend_from_slice(&vec);
252
253 Ok(())
254 }
255
256 write_func!(write_byte_array(&[u8]));
257
258 fn begin_array<W: ?Sized + io::Write>(&mut self, _writer: &mut W) -> io::Result<()> {
259 self.token.push(Token::BeginArray(self.level));
260 self.level += 1;
261
262 Ok(())
263 }
264
265 fn end_array<W: ?Sized + io::Write>(&mut self, writer: &mut W) -> io::Result<()> {
266 self.token.push(Token::EndArray);
267 self.level -= 1;
268
269 self.format_json(writer)
270 }
271
272 fn begin_array_value<W: ?Sized + io::Write>(
273 &mut self,
274 _writer: &mut W,
275 _first: bool,
276 ) -> io::Result<()> {
277 Ok(())
278 }
279
280 fn end_array_value<W: ?Sized + io::Write>(&mut self, _writer: &mut W) -> io::Result<()> {
281 Ok(())
282 }
283
284 fn begin_object<W: ?Sized + io::Write>(&mut self, _writer: &mut W) -> io::Result<()> {
285 self.token.push(Token::BeginObject(self.level));
286 self.level += 1;
287
288 Ok(())
289 }
290
291 fn end_object<W: ?Sized + io::Write>(&mut self, writer: &mut W) -> io::Result<()> {
292 self.token.push(Token::EndObject);
293 self.level -= 1;
294
295 self.format_json(writer)
296 }
297
298 fn begin_object_key<W: ?Sized + io::Write>(
299 &mut self,
300 _writer: &mut W,
301 _first: bool,
302 ) -> io::Result<()> {
303 Ok(())
304 }
305
306 fn end_object_key<W: ?Sized + io::Write>(&mut self, _writer: &mut W) -> io::Result<()> {
307 Ok(())
308 }
309
310 fn begin_object_value<W: ?Sized + io::Write>(&mut self, _writer: &mut W) -> io::Result<()> {
311 Ok(())
312 }
313
314 fn end_object_value<W: ?Sized + io::Write>(&mut self, _writer: &mut W) -> io::Result<()> {
315 Ok(())
316 }
317
318 write_func!(write_raw_fragment(&str));
319}