1use std::io::{self, Write};
6
7use crate::{serde::tri, util::string::format_string, writer::WriteExt};
8
9pub trait Formatter: Clone {
12 #[inline]
14 fn write_null<W>(&mut self, writer: &mut W) -> io::Result<()>
15 where
16 W: ?Sized + Write,
17 {
18 writer.write_all(b"null")
19 }
20
21 #[inline]
23 fn write_bool<W>(&mut self, writer: &mut W, value: bool) -> io::Result<()>
24 where
25 W: ?Sized + Write,
26 {
27 if value {
28 writer.write_all(b"true")
29 } else {
30 writer.write_all(b"false")
31 }
32 }
33
34 #[inline]
36 fn write_i8<W>(&mut self, writer: &mut W, value: i8) -> io::Result<()>
37 where
38 W: ?Sized + Write,
39 {
40 let mut buffer = itoa::Buffer::new();
41 let s = buffer.format(value);
42 writer.write_all(s.as_bytes())
43 }
44
45 #[inline]
47 fn write_i16<W>(&mut self, writer: &mut W, value: i16) -> io::Result<()>
48 where
49 W: ?Sized + Write,
50 {
51 let mut buffer = itoa::Buffer::new();
52 let s = buffer.format(value);
53 writer.write_all(s.as_bytes())
54 }
55
56 #[inline]
58 fn write_i32<W>(&mut self, writer: &mut W, value: i32) -> io::Result<()>
59 where
60 W: ?Sized + Write,
61 {
62 let mut buffer = itoa::Buffer::new();
63 let s = buffer.format(value);
64 writer.write_all(s.as_bytes())
65 }
66
67 #[inline]
69 fn write_i64<W>(&mut self, writer: &mut W, value: i64) -> io::Result<()>
70 where
71 W: ?Sized + Write,
72 {
73 let mut buffer = itoa::Buffer::new();
74 let s = buffer.format(value);
75 writer.write_all(s.as_bytes())
76 }
77
78 #[inline]
80 fn write_i128<W>(&mut self, writer: &mut W, value: i128) -> io::Result<()>
81 where
82 W: ?Sized + Write,
83 {
84 let mut buffer = itoa::Buffer::new();
85 let s = buffer.format(value);
86 writer.write_all(s.as_bytes())
87 }
88
89 #[inline]
91 fn write_u8<W>(&mut self, writer: &mut W, value: u8) -> io::Result<()>
92 where
93 W: ?Sized + Write,
94 {
95 let mut buffer = itoa::Buffer::new();
96 let s = buffer.format(value);
97 writer.write_all(s.as_bytes())
98 }
99
100 #[inline]
102 fn write_u16<W>(&mut self, writer: &mut W, value: u16) -> io::Result<()>
103 where
104 W: ?Sized + Write,
105 {
106 let mut buffer = itoa::Buffer::new();
107 let s = buffer.format(value);
108 writer.write_all(s.as_bytes())
109 }
110
111 #[inline]
113 fn write_u32<W>(&mut self, writer: &mut W, value: u32) -> io::Result<()>
114 where
115 W: ?Sized + Write,
116 {
117 let mut buffer = itoa::Buffer::new();
118 let s = buffer.format(value);
119 writer.write_all(s.as_bytes())
120 }
121
122 #[inline]
124 fn write_u64<W>(&mut self, writer: &mut W, value: u64) -> io::Result<()>
125 where
126 W: ?Sized + Write,
127 {
128 let mut buffer = itoa::Buffer::new();
129 let s = buffer.format(value);
130 writer.write_all(s.as_bytes())
131 }
132
133 #[inline]
135 fn write_u128<W>(&mut self, writer: &mut W, value: u128) -> io::Result<()>
136 where
137 W: ?Sized + Write,
138 {
139 let mut buffer = itoa::Buffer::new();
140 let s = buffer.format(value);
141 writer.write_all(s.as_bytes())
142 }
143
144 #[inline]
146 fn write_f32<W>(&mut self, writer: &mut W, value: f32) -> io::Result<()>
147 where
148 W: ?Sized + Write,
149 {
150 #[cfg(feature = "non_trailing_zero")]
151 if value.fract() == 0.0 && value <= (i64::MAX as f32) && value >= (i64::MIN as f32) {
152 return self.write_i64(writer, value as i64);
153 }
154
155 let mut buffer = ryu::Buffer::new();
156 let s = buffer.format_finite(value);
157 writer.write_all(s.as_bytes())
158 }
159
160 #[inline]
162 fn write_f64<W>(&mut self, writer: &mut W, value: f64) -> io::Result<()>
163 where
164 W: ?Sized + Write,
165 {
166 #[cfg(feature = "non_trailing_zero")]
167 if value.fract() == 0.0 && value <= (i64::MAX as f64) && value >= (i64::MIN as f64) {
168 return self.write_i64(writer, value as i64);
169 }
170
171 let mut buffer = ryu::Buffer::new();
172 let s = buffer.format_finite(value);
173 writer.write_all(s.as_bytes())
174 }
175
176 #[inline]
178 fn write_number_str<W>(&mut self, writer: &mut W, value: &str) -> io::Result<()>
179 where
180 W: ?Sized + Write,
181 {
182 writer.write_all(value.as_bytes())
183 }
184
185 #[inline]
188 fn write_string_fast<W>(
189 &mut self,
190 writer: &mut W,
191 value: &str,
192 need_quote: bool,
193 ) -> io::Result<()>
194 where
195 W: ?Sized + WriteExt,
196 {
197 let buf = writer.reserve_with(value.len() * 6 + 32 + 3)?;
198 let cnt = format_string(value, buf, need_quote);
199 unsafe { writer.flush_len(cnt)? };
200 Ok(())
201 }
202
203 fn write_byte_array<W>(&mut self, writer: &mut W, value: &[u8]) -> io::Result<()>
207 where
208 W: ?Sized + Write,
209 {
210 tri!(self.begin_array(writer));
211 let mut first = true;
212 for byte in value {
213 tri!(self.begin_array_value(writer, first));
214 tri!(self.write_u8(writer, *byte));
215 tri!(self.end_array_value(writer));
216 first = false;
217 }
218 self.end_array(writer)
219 }
220
221 #[inline]
223 fn begin_string<W>(&mut self, writer: &mut W) -> io::Result<()>
224 where
225 W: ?Sized + Write,
226 {
227 writer.write_all(b"\"")
228 }
229
230 #[inline]
232 fn end_string<W>(&mut self, writer: &mut W) -> io::Result<()>
233 where
234 W: ?Sized + Write,
235 {
236 writer.write_all(b"\"")
237 }
238
239 #[inline]
242 fn begin_array<W>(&mut self, writer: &mut W) -> io::Result<()>
243 where
244 W: ?Sized + Write,
245 {
246 writer.write_all(b"[")
247 }
248
249 #[inline]
252 fn end_array<W>(&mut self, writer: &mut W) -> io::Result<()>
253 where
254 W: ?Sized + Write,
255 {
256 writer.write_all(b"]")
257 }
258
259 #[inline]
262 fn begin_array_value<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
263 where
264 W: ?Sized + Write,
265 {
266 if first {
267 Ok(())
268 } else {
269 writer.write_all(b",")
270 }
271 }
272
273 #[inline]
275 fn end_array_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
276 where
277 W: ?Sized + Write,
278 {
279 Ok(())
280 }
281
282 #[inline]
285 fn begin_object<W>(&mut self, writer: &mut W) -> io::Result<()>
286 where
287 W: ?Sized + Write,
288 {
289 writer.write_all(b"{")
290 }
291
292 #[inline]
295 fn end_object<W>(&mut self, writer: &mut W) -> io::Result<()>
296 where
297 W: ?Sized + Write,
298 {
299 writer.write_all(b"}")
300 }
301
302 #[inline]
304 fn begin_object_key<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
305 where
306 W: ?Sized + Write,
307 {
308 if first {
309 Ok(())
310 } else {
311 writer.write_all(b",")
312 }
313 }
314
315 #[inline]
319 fn end_object_key<W>(&mut self, _writer: &mut W) -> io::Result<()>
320 where
321 W: ?Sized + Write,
322 {
323 Ok(())
324 }
325
326 #[inline]
330 fn begin_object_value<W>(&mut self, writer: &mut W) -> io::Result<()>
331 where
332 W: ?Sized + Write,
333 {
334 writer.write_all(b":")
335 }
336
337 #[inline]
339 fn end_object_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
340 where
341 W: ?Sized + Write,
342 {
343 Ok(())
344 }
345
346 #[inline]
349 fn write_raw_value<W>(&mut self, writer: &mut W, raw: &str) -> io::Result<()>
350 where
351 W: ?Sized + Write,
352 {
353 writer.write_all(raw.as_bytes())
354 }
355}
356
357#[derive(Clone, Debug)]
359pub struct CompactFormatter;
360
361impl Formatter for CompactFormatter {}
362
363#[derive(Clone, Debug)]
365pub struct PrettyFormatter<'a> {
366 current_indent: usize,
367 has_value: bool,
368 indent: &'a [u8],
369}
370
371impl<'a> PrettyFormatter<'a> {
372 pub fn new() -> Self {
374 PrettyFormatter::with_indent(b" ")
375 }
376
377 pub fn with_indent(indent: &'a [u8]) -> Self {
379 PrettyFormatter {
380 current_indent: 0,
381 has_value: false,
382 indent,
383 }
384 }
385}
386
387impl<'a> Default for PrettyFormatter<'a> {
388 fn default() -> Self {
389 PrettyFormatter::new()
390 }
391}
392
393impl<'a> Formatter for PrettyFormatter<'a> {
394 #[inline]
395 fn begin_array<W>(&mut self, writer: &mut W) -> io::Result<()>
396 where
397 W: ?Sized + Write,
398 {
399 self.current_indent += 1;
400 self.has_value = false;
401 writer.write_all(b"[")
402 }
403
404 #[inline]
405 fn end_array<W>(&mut self, writer: &mut W) -> io::Result<()>
406 where
407 W: ?Sized + Write,
408 {
409 self.current_indent -= 1;
410
411 if self.has_value {
412 tri!(writer.write_all(b"\n"));
413 tri!(indent(writer, self.current_indent, self.indent));
414 }
415
416 writer.write_all(b"]")
417 }
418
419 #[inline]
420 fn begin_array_value<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
421 where
422 W: ?Sized + Write,
423 {
424 tri!(writer.write_all(if first { b"\n" } else { b",\n" }));
425 indent(writer, self.current_indent, self.indent)
426 }
427
428 #[inline]
429 fn end_array_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
430 where
431 W: ?Sized + Write,
432 {
433 self.has_value = true;
434 Ok(())
435 }
436
437 #[inline]
438 fn begin_object<W>(&mut self, writer: &mut W) -> io::Result<()>
439 where
440 W: ?Sized + Write,
441 {
442 self.current_indent += 1;
443 self.has_value = false;
444 writer.write_all(b"{")
445 }
446
447 #[inline]
448 fn end_object<W>(&mut self, writer: &mut W) -> io::Result<()>
449 where
450 W: ?Sized + Write,
451 {
452 self.current_indent -= 1;
453
454 if self.has_value {
455 tri!(writer.write_all(b"\n"));
456 tri!(indent(writer, self.current_indent, self.indent));
457 }
458
459 writer.write_all(b"}")
460 }
461
462 #[inline]
463 fn begin_object_key<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
464 where
465 W: ?Sized + Write,
466 {
467 tri!(writer.write_all(if first { b"\n" } else { b",\n" }));
468 indent(writer, self.current_indent, self.indent)
469 }
470
471 #[inline]
472 fn begin_object_value<W>(&mut self, writer: &mut W) -> io::Result<()>
473 where
474 W: ?Sized + Write,
475 {
476 writer.write_all(b": ")
477 }
478
479 #[inline]
480 fn end_object_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
481 where
482 W: ?Sized + Write,
483 {
484 self.has_value = true;
485 Ok(())
486 }
487}
488
489fn indent<W>(wr: &mut W, n: usize, s: &[u8]) -> io::Result<()>
490where
491 W: ?Sized + Write,
492{
493 for _ in 0..n {
494 tri!(wr.write_all(s));
495 }
496
497 Ok(())
498}