1use ansi_term;
2use dtoa;
3
4use crate::error;
5use crate::value;
6use itoa;
7use serde;
8use serde_json;
9use std::fmt;
10use std::io;
11use std::str;
12
13pub struct Source<'de, R>(
14 serde_json::StreamDeserializer<'de, serde_json::de::IoRead<R>, value::Value>,
15)
16where
17 R: io::Read;
18
19pub struct Sink<W, F>(W, F)
20where
21 W: io::Write,
22 F: Clone + serde_json::ser::Formatter;
23
24#[derive(Clone, Debug)]
25pub struct ReadableFormatter {
26 current_indent: usize,
27 is_in_object_key: bool,
28 has_value: bool,
29
30 null_style: ansi_term::Style,
31
32 true_style: ansi_term::Style,
33 false_style: ansi_term::Style,
34
35 number_style: ansi_term::Style,
36
37 string_quote_style: ansi_term::Style,
38 string_char_style: ansi_term::Style,
39 string_escape_style: ansi_term::Style,
40
41 array_bracket_style: ansi_term::Style,
42 array_comma_style: ansi_term::Style,
43
44 object_brace_style: ansi_term::Style,
45 object_colon_style: ansi_term::Style,
46 object_comma_style: ansi_term::Style,
47 object_key_quote_style: ansi_term::Style,
48 object_key_char_style: ansi_term::Style,
49 object_key_escape_style: ansi_term::Style,
50}
51
52#[inline]
53pub fn source<'de, R>(r: R) -> Source<'de, R>
54where
55 R: io::Read,
56{
57 Source(serde_json::Deserializer::new(serde_json::de::IoRead::new(r)).into_iter())
58}
59
60#[inline]
61pub fn sink_compact<W>(w: W) -> Sink<W, serde_json::ser::CompactFormatter>
62where
63 W: io::Write,
64{
65 Sink(w, serde_json::ser::CompactFormatter)
66}
67
68#[inline]
69pub fn sink_readable<W>(w: W) -> Sink<W, ReadableFormatter>
70where
71 W: io::Write,
72{
73 Sink(w, ReadableFormatter::new())
74}
75
76#[inline]
77pub fn sink_indented<'a, W>(w: W) -> Sink<W, serde_json::ser::PrettyFormatter<'a>>
78where
79 W: io::Write,
80{
81 Sink(w, serde_json::ser::PrettyFormatter::new())
82}
83
84impl<'de, R> value::Source for Source<'de, R>
85where
86 R: io::Read,
87{
88 #[inline]
89 fn read(&mut self) -> error::Result<Option<value::Value>> {
90 match self.0.next() {
91 Some(Ok(v)) => Ok(Some(v)),
92 Some(Err(e)) => Err(error::Error::from(e)),
93 None => Ok(None),
94 }
95 }
96}
97
98impl<W, F> value::Sink for Sink<W, F>
99where
100 W: io::Write,
101 F: Clone + serde_json::ser::Formatter,
102{
103 #[inline]
104 fn write(&mut self, v: value::Value) -> error::Result<()> {
105 {
106 let mut serializer =
107 serde_json::ser::Serializer::with_formatter(&mut self.0, self.1.clone());
108 serde::Serialize::serialize(&v, &mut serializer)?;
109 }
110 self.0.write_all(b"\n")?;
111 Ok(())
112 }
113}
114
115impl ReadableFormatter {
116 fn new() -> Self {
117 use ansi_term::{Colour, Style};
118
119 Self {
120 current_indent: 0,
121 is_in_object_key: false,
122 has_value: false,
123
124 null_style: Colour::Black.dimmed().bold().italic(),
125
126 true_style: Colour::Green.bold().italic(),
127 false_style: Colour::Red.bold().italic(),
128
129 number_style: Colour::Blue.normal(),
130
131 string_quote_style: Colour::Green.dimmed(),
132 string_char_style: Colour::Green.normal(),
133 string_escape_style: Colour::Green.dimmed(),
134
135 array_bracket_style: Style::default().bold(),
136 array_comma_style: Style::default().bold(),
137
138 object_brace_style: Style::default().bold(),
139 object_colon_style: Style::default().bold(),
140 object_comma_style: Style::default().bold(),
141 object_key_quote_style: Colour::Blue.dimmed(),
142 object_key_char_style: Colour::Blue.normal(),
143 object_key_escape_style: Colour::Blue.dimmed(),
144 }
145 }
146
147 #[inline]
149 fn write_integer<W, I>(&mut self, mut writer: &mut W, value: I) -> io::Result<()>
150 where
151 W: io::Write + ?Sized,
152 I: itoa::Integer,
153 {
154 write!(writer, "{}", self.number_style.prefix())?;
155 itoa::write(&mut writer, value)?;
156 write!(writer, "{}", self.number_style.suffix())?;
157 Ok(())
158 }
159
160 #[inline]
163 fn write_floating<W, F>(&mut self, mut writer: &mut W, value: F) -> io::Result<()>
164 where
165 W: io::Write + ?Sized,
166 F: dtoa::Floating,
167 {
168 write!(writer, "{}", self.number_style.prefix())?;
169 dtoa::write(&mut writer, value)?;
170 write!(writer, "{}", self.number_style.suffix())?;
171 Ok(())
172 }
173}
174
175impl serde_json::ser::Formatter for ReadableFormatter {
176 #[inline]
178 fn write_null<W>(&mut self, writer: &mut W) -> io::Result<()>
179 where
180 W: io::Write + ?Sized,
181 {
182 write!(writer, "{}", self.null_style.paint("null")).map_err(From::from)
183 }
184
185 #[inline]
187 fn write_bool<W>(&mut self, writer: &mut W, value: bool) -> io::Result<()>
188 where
189 W: io::Write + ?Sized,
190 {
191 let s = if value {
192 self.true_style.paint("true")
193 } else {
194 self.false_style.paint("false")
195 };
196 write!(writer, "{}", s).map_err(From::from)
197 }
198
199 #[inline]
200 fn write_i8<W>(&mut self, writer: &mut W, value: i8) -> io::Result<()>
201 where
202 W: io::Write + ?Sized,
203 {
204 self.write_integer(writer, value)
205 }
206
207 #[inline]
208 fn write_i16<W>(&mut self, writer: &mut W, value: i16) -> io::Result<()>
209 where
210 W: io::Write + ?Sized,
211 {
212 self.write_integer(writer, value)
213 }
214
215 #[inline]
216 fn write_i32<W>(&mut self, writer: &mut W, value: i32) -> io::Result<()>
217 where
218 W: io::Write + ?Sized,
219 {
220 self.write_integer(writer, value)
221 }
222
223 #[inline]
224 fn write_i64<W>(&mut self, writer: &mut W, value: i64) -> io::Result<()>
225 where
226 W: io::Write + ?Sized,
227 {
228 self.write_integer(writer, value)
229 }
230
231 #[inline]
232 fn write_u8<W>(&mut self, writer: &mut W, value: u8) -> io::Result<()>
233 where
234 W: io::Write + ?Sized,
235 {
236 self.write_integer(writer, value)
237 }
238
239 #[inline]
240 fn write_u16<W>(&mut self, writer: &mut W, value: u16) -> io::Result<()>
241 where
242 W: io::Write + ?Sized,
243 {
244 self.write_integer(writer, value)
245 }
246
247 #[inline]
248 fn write_u32<W>(&mut self, writer: &mut W, value: u32) -> io::Result<()>
249 where
250 W: io::Write + ?Sized,
251 {
252 self.write_integer(writer, value)
253 }
254
255 #[inline]
256 fn write_u64<W>(&mut self, writer: &mut W, value: u64) -> io::Result<()>
257 where
258 W: io::Write + ?Sized,
259 {
260 self.write_integer(writer, value)
261 }
262
263 #[inline]
264 fn write_f32<W>(&mut self, writer: &mut W, value: f32) -> io::Result<()>
265 where
266 W: io::Write + ?Sized,
267 {
268 self.write_floating(writer, value)
269 }
270
271 #[inline]
272 fn write_f64<W>(&mut self, writer: &mut W, value: f64) -> io::Result<()>
273 where
274 W: io::Write + ?Sized,
275 {
276 self.write_floating(writer, value)
277 }
278
279 #[inline]
282 fn begin_string<W>(&mut self, writer: &mut W) -> io::Result<()>
283 where
284 W: io::Write + ?Sized,
285 {
286 let style = if self.is_in_object_key {
287 self.object_key_quote_style
288 } else {
289 self.string_quote_style
290 };
291
292 write!(writer, "{}", style.paint("\"")).map_err(From::from)
293 }
294
295 #[inline]
298 fn end_string<W>(&mut self, writer: &mut W) -> io::Result<()>
299 where
300 W: io::Write + ?Sized,
301 {
302 let style = if self.is_in_object_key {
303 self.object_key_quote_style
304 } else {
305 self.string_quote_style
306 };
307
308 write!(writer, "{}", style.paint("\"")).map_err(From::from)
309 }
310
311 #[inline]
314 fn write_string_fragment<W>(&mut self, writer: &mut W, fragment: &str) -> io::Result<()>
315 where
316 W: io::Write + ?Sized,
317 {
318 let style = if self.is_in_object_key {
319 self.object_key_char_style
320 } else {
321 self.string_char_style
322 };
323
324 write!(writer, "{}", style.paint(fragment)).map_err(From::from)
325 }
326
327 #[inline]
329 fn write_char_escape<W>(
330 &mut self,
331 writer: &mut W,
332 char_escape: serde_json::ser::CharEscape,
333 ) -> io::Result<()>
334 where
335 W: io::Write + ?Sized,
336 {
337 use serde_json::ser::CharEscape::*;
338
339 let style = if self.is_in_object_key {
340 self.object_key_escape_style
341 } else {
342 self.string_escape_style
343 };
344
345 let s = match char_escape {
346 Quote => "\\\"",
347 ReverseSolidus => "\\\\",
348 Solidus => "\\/",
349 Backspace => "\\b",
350 FormFeed => "\\f",
351 LineFeed => "\\n",
352 CarriageReturn => "\\r",
353 Tab => "\\t",
354 AsciiControl(byte) => {
355 static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef";
356 let bytes = &[
357 b'\\',
358 b'u',
359 b'0',
360 b'0',
361 HEX_DIGITS[(byte >> 4) as usize],
362 HEX_DIGITS[(byte & 0xF) as usize],
363 ];
364 let s = unsafe { str::from_utf8_unchecked(bytes) };
365
366 return write!(writer, "{}", style.paint(s)).map_err(From::from);
368 }
369 };
370
371 write!(writer, "{}", style.paint(s)).map_err(From::from)
372 }
373
374 #[inline]
377 fn begin_array<W>(&mut self, writer: &mut W) -> io::Result<()>
378 where
379 W: io::Write + ?Sized,
380 {
381 self.current_indent += 1;
382 self.has_value = false;
383
384 write!(writer, "{}", self.array_bracket_style.paint("[")).map_err(From::from)
385 }
386
387 #[inline]
390 fn end_array<W>(&mut self, writer: &mut W) -> io::Result<()>
391 where
392 W: io::Write + ?Sized,
393 {
394 self.current_indent -= 1;
395
396 if self.has_value {
397 writeln!(writer)?;
398 indent(writer, self.current_indent)?;
399 }
400
401 write!(writer, "{}", self.array_bracket_style.paint("]")).map_err(From::from)
402 }
403
404 #[inline]
407 fn begin_array_value<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
408 where
409 W: io::Write + ?Sized,
410 {
411 if !first {
412 write!(writer, "{}", self.array_comma_style.paint(","))?;
413 }
414
415 writeln!(writer)?;
416 indent(writer, self.current_indent)?;
417 Ok(())
418 }
419
420 #[inline]
422 fn end_array_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
423 where
424 W: io::Write + ?Sized,
425 {
426 self.has_value = true;
427 Ok(())
428 }
429
430 #[inline]
433 fn begin_object<W>(&mut self, writer: &mut W) -> io::Result<()>
434 where
435 W: io::Write + ?Sized,
436 {
437 self.current_indent += 1;
438 self.has_value = false;
439
440 write!(writer, "{}", self.object_brace_style.paint("{")).map_err(From::from)
441 }
442
443 #[inline]
446 fn end_object<W>(&mut self, writer: &mut W) -> io::Result<()>
447 where
448 W: io::Write + ?Sized,
449 {
450 self.current_indent -= 1;
451
452 if self.has_value {
453 writeln!(writer)?;
454 indent(writer, self.current_indent)?;
455 }
456
457 write!(writer, "{}", self.object_brace_style.paint("}")).map_err(From::from)
458 }
459
460 #[inline]
462 fn begin_object_key<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
463 where
464 W: io::Write + ?Sized,
465 {
466 self.is_in_object_key = true;
467
468 if !first {
469 write!(writer, "{}", self.object_comma_style.paint(","))?;
470 }
471
472 writeln!(writer)?;
473 indent(writer, self.current_indent)?;
474 Ok(())
475 }
476
477 #[inline]
481 fn end_object_key<W>(&mut self, _writer: &mut W) -> io::Result<()>
482 where
483 W: io::Write + ?Sized,
484 {
485 self.is_in_object_key = false;
486 Ok(())
487 }
488
489 #[inline]
493 fn begin_object_value<W>(&mut self, writer: &mut W) -> io::Result<()>
494 where
495 W: io::Write + ?Sized,
496 {
497 write!(writer, "{}", self.object_colon_style.paint(": ")).map_err(From::from)
498 }
499
500 #[inline]
502 fn end_object_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
503 where
504 W: io::Write + ?Sized,
505 {
506 self.has_value = true;
507 Ok(())
508 }
509}
510
511fn indent<W>(wr: &mut W, n: usize) -> io::Result<()>
512where
513 W: io::Write + ?Sized,
514{
515 for _ in 0..n {
516 wr.write_all(b" ")?;
517 }
518
519 Ok(())
520}
521
522impl<'de, R> fmt::Debug for Source<'de, R>
523where
524 R: io::Read,
525{
526 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
527 f.debug_struct("CsvSource").finish()
528 }
529}
530
531impl<W, F> fmt::Debug for Sink<W, F>
532where
533 W: io::Write,
534 F: Clone + serde_json::ser::Formatter,
535{
536 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
537 f.debug_struct("JsonSink").finish()
538 }
539}