json_color/
lib.rs

1extern crate colored;
2extern crate serde;
3extern crate serde_json;
4
5use colored::Colorize;
6use serde::ser::Serialize;
7use serde_json::ser::{CharEscape, Formatter, Serializer};
8use serde_json::value::Value;
9
10use std::io::{Result, Write};
11use std::str;
12
13macro_rules! colorize {
14    ($s:expr, $color:expr) => {{
15        let colored_string = match *$color {
16            Color::Black => $s.black(),
17            Color::Blue => $s.blue(),
18            Color::Cyan => $s.cyan(),
19            Color::Green => $s.green(),
20            Color::Magenta => $s.magenta(),
21            Color::Purple => $s.purple(),
22            Color::Red => $s.red(),
23            Color::White => $s.white(),
24            Color::Yellow => $s.yellow(),
25
26            Color::Plain => $s.normal(),
27        };
28
29        colored_string.to_string()
30    }};
31}
32
33/// The set of available colors for the various JSON components.
34#[derive(Clone)]
35pub enum Color {
36    Black,
37    Blue,
38    Cyan,
39    Green,
40    Magenta,
41    Purple,
42    Red,
43    White,
44    Yellow,
45
46    /// Default color
47    Plain,
48}
49
50impl Default for Color {
51    fn default() -> Self {
52        Color::Plain
53    }
54}
55
56#[derive(Default)]
57pub struct ColorizerBuilder {
58    null: Color,
59    boolean: Color,
60    number: Color,
61    string: Color,
62    key: Color,
63    escape_sequence: Color,
64}
65
66impl ColorizerBuilder {
67    fn new() -> Self {
68        Default::default()
69    }
70
71    /// Sets the color of the null value.
72    pub fn null(&mut self, color: Color) -> &mut Self {
73        self.null = color;
74        self
75    }
76
77    /// Sets the color of boolean values.
78    pub fn boolean(&mut self, color: Color) -> &mut Self {
79        self.boolean = color;
80        self
81    }
82
83    /// Sets the color of number values.
84    pub fn number(&mut self, color: Color) -> &mut Self {
85        self.number = color;
86        self
87    }
88
89    /// Sets the color of string values.
90    pub fn string(&mut self, color: Color) -> &mut Self {
91        self.string = color;
92        self
93    }
94
95    /// Sets the color of JSON object keys.
96    pub fn key(&mut self, color: Color) -> &mut Self {
97        self.key = color;
98        self
99    }
100
101    /// Sets the color of escape sequences within string values.
102    pub fn escape_sequence(&mut self, color: Color) -> &mut Self {
103        self.escape_sequence = color;
104        self
105    }
106
107    /// Constructs a new Colorizer.
108    pub fn build(&self) -> Colorizer {
109        Colorizer {
110            null: self.null.clone(),
111            boolean: self.boolean.clone(),
112            number: self.number.clone(),
113            string: self.string.clone(),
114            key: self.key.clone(),
115            escape_sequence: self.escape_sequence.clone(),
116            indent_level: 0,
117            current_is_key: false,
118        }
119    }
120}
121
122/// A struct representing a specific configuration of colors for the various JSON components.
123#[derive(Clone, Default)]
124pub struct Colorizer {
125    pub null: Color,
126    pub boolean: Color,
127    pub number: Color,
128    pub string: Color,
129    pub key: Color,
130    escape_sequence: Color,
131    indent_level: usize,
132    current_is_key: bool,
133}
134
135impl Colorizer {
136    /// Start builder a new Colorizer.
137    pub fn new() -> ColorizerBuilder {
138        ColorizerBuilder::new()
139    }
140
141    /// Creates a new Colorizer with a predefined set of colors for the various JSON components.
142    ///
143    /// Use this if you want your JSON to be colored, but don't care about the specific colors.
144    pub fn arbitrary() -> Self {
145        Colorizer::new()
146            .null(Color::Cyan)
147            .boolean(Color::Yellow)
148            .number(Color::Magenta)
149            .string(Color::Green)
150            .key(Color::Blue)
151            .escape_sequence(Color::Red)
152            .build()
153    }
154
155    /// Colorize a JSON string. Currently, all strings will be pretty-printed (with indentation and
156    /// spacing).
157    ///
158    /// # Errors
159    ///
160    /// An error is returned if the string is invalid JSON or an I/O error occurs.
161    pub fn colorize_json_str(&self, s: &str) -> Result<String> {
162        let value: Value = ::serde_json::from_str(s)?;
163        let vec = self.to_vec(&value)?;
164        let string = unsafe { String::from_utf8_unchecked(vec) };
165        Ok(string)
166    }
167
168    /// Colorize a JSON string and write the result to `writer`.
169    ///
170    /// Currently, all strings will be pretty-printed (with indentation and spacing).
171    ///
172    /// # Errors
173    ///
174    /// An error is returned if the string is invalid JSON or an I/O error occurs.
175    pub fn colorize_to_writer<W>(&self, s: &str, writer: &mut W) -> Result<()>
176    where
177        W: Write,
178    {
179        let value: Value = ::serde_json::from_str(s)?;
180        self.to_writer(writer, &value)
181    }
182
183    fn to_vec<T: ?Sized>(&self, value: &T) -> Result<Vec<u8>>
184    where
185        T: Serialize,
186    {
187        let mut writer = Vec::with_capacity(128);
188
189        self.to_writer(&mut writer, value)?;
190        Ok(writer)
191    }
192
193    fn to_writer<W: ?Sized, T: ?Sized>(&self, writer: &mut W, value: &T) -> Result<()>
194    where
195        W: Write,
196        T: Serialize,
197    {
198        let mut ser = Serializer::with_formatter(writer, self.clone());
199        value.serialize(&mut ser)?;
200        Ok(())
201    }
202
203    #[inline]
204    fn get_indentation(&self) -> String {
205        (0..self.indent_level * 2).map(|_| ' ').collect()
206    }
207
208    #[inline]
209    fn get_string_color(&self) -> &Color {
210        if self.current_is_key {
211            &self.key
212        } else {
213            &self.string
214        }
215    }
216}
217
218impl Formatter for Colorizer {
219    fn write_null<W: ?Sized>(&mut self, writer: &mut W) -> Result<()>
220    where
221        W: Write,
222    {
223        write!(writer, "{}", colorize!("null", &self.null))
224    }
225
226    fn write_bool<W: ?Sized>(&mut self, writer: &mut W, value: bool) -> Result<()>
227    where
228        W: Write,
229    {
230        let value_as_string = format!("{}", value);
231        write!(writer, "{}", colorize!(&value_as_string, &self.boolean))
232    }
233
234    fn write_i8<W: ?Sized>(&mut self, writer: &mut W, value: i8) -> Result<()>
235    where
236        W: Write,
237    {
238        let value_as_string = format!("{}", value);
239        write!(writer, "{}", colorize!(&value_as_string, &self.number))
240    }
241
242    fn write_i16<W: ?Sized>(&mut self, writer: &mut W, value: i16) -> Result<()>
243    where
244        W: Write,
245    {
246        let value_as_string = format!("{}", value);
247        write!(writer, "{}", colorize!(&value_as_string, &self.number))
248    }
249
250    fn write_i32<W: ?Sized>(&mut self, writer: &mut W, value: i32) -> Result<()>
251    where
252        W: Write,
253    {
254        let value_as_string = format!("{}", value);
255        write!(writer, "{}", colorize!(&value_as_string, &self.number))
256    }
257
258    fn write_i64<W: ?Sized>(&mut self, writer: &mut W, value: i64) -> Result<()>
259    where
260        W: Write,
261    {
262        let value_as_string = format!("{}", value);
263        write!(writer, "{}", colorize!(&value_as_string, &self.number))
264    }
265
266    fn write_u8<W: ?Sized>(&mut self, writer: &mut W, value: u8) -> Result<()>
267    where
268        W: Write,
269    {
270        let value_as_string = format!("{}", value);
271        write!(writer, "{}", colorize!(&value_as_string, &self.number))
272    }
273
274    fn write_u16<W: ?Sized>(&mut self, writer: &mut W, value: u16) -> Result<()>
275    where
276        W: Write,
277    {
278        let value_as_string = format!("{}", value);
279        write!(writer, "{}", colorize!(&value_as_string, &self.number))
280    }
281
282    fn write_u32<W: ?Sized>(&mut self, writer: &mut W, value: u32) -> Result<()>
283    where
284        W: Write,
285    {
286        let value_as_string = format!("{}", value);
287        write!(writer, "{}", colorize!(&value_as_string, &self.number))
288    }
289
290    fn write_u64<W: ?Sized>(&mut self, writer: &mut W, value: u64) -> Result<()>
291    where
292        W: Write,
293    {
294        let value_as_string = format!("{}", value);
295        write!(writer, "{}", colorize!(&value_as_string, &self.number))
296    }
297
298    fn write_f32<W: ?Sized>(&mut self, writer: &mut W, value: f32) -> Result<()>
299    where
300        W: Write,
301    {
302        let value_as_string = format!("{}", value);
303        write!(writer, "{}", colorize!(&value_as_string, &self.number))
304    }
305
306    fn write_f64<W: ?Sized>(&mut self, writer: &mut W, value: f64) -> Result<()>
307    where
308        W: Write,
309    {
310        let value_as_string = format!("{}", value);
311        write!(writer, "{}", colorize!(&value_as_string, &self.number))
312    }
313
314    fn begin_string<W: ?Sized>(&mut self, writer: &mut W) -> Result<()>
315    where
316        W: Write,
317    {
318        write!(writer, "{}", colorize!("\"", self.get_string_color()))
319    }
320
321    fn end_string<W: ?Sized>(&mut self, writer: &mut W) -> Result<()>
322    where
323        W: Write,
324    {
325        write!(writer, "{}", colorize!("\"", self.get_string_color()))
326    }
327
328    fn write_string_fragment<W: ?Sized>(&mut self, writer: &mut W, fragment: &str) -> Result<()>
329    where
330        W: Write,
331    {
332        write!(writer, "{}", colorize!(fragment, self.get_string_color()))
333    }
334
335    fn write_char_escape<W: ?Sized>(
336        &mut self,
337        writer: &mut W,
338        char_escape: CharEscape,
339    ) -> Result<()>
340    where
341        W: Write,
342    {
343        let s = match char_escape {
344            CharEscape::Quote => "\\\"",
345            CharEscape::ReverseSolidus => "\\\\",
346            CharEscape::Solidus => "\\/",
347            CharEscape::Backspace => "\\b",
348            CharEscape::FormFeed => "\\f",
349            CharEscape::LineFeed => "\\n",
350            CharEscape::CarriageReturn => "\\r",
351            CharEscape::Tab => "\\t",
352            CharEscape::AsciiControl(byte) => {
353                let hex_digits = [
354                    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
355                ];
356
357                let mut bytes = "\\u00".to_string();
358                bytes.push(hex_digits[(byte >> 4) as usize]);
359                bytes.push(hex_digits[(byte & 0xF) as usize]);
360
361                return write!(writer, "{}", colorize!(bytes, &self.escape_sequence));
362            }
363        };
364
365        write!(writer, "{}", colorize!(s, &self.escape_sequence))
366    }
367
368    fn begin_array<W: ?Sized>(&mut self, writer: &mut W) -> Result<()>
369    where
370        W: Write,
371    {
372        self.indent_level += 1;
373        write!(writer, "[")
374    }
375
376    fn end_array<W: ?Sized>(&mut self, writer: &mut W) -> Result<()>
377    where
378        W: Write,
379    {
380        self.indent_level -= 1;
381        write!(writer, "\n{}]", self.get_indentation())
382    }
383
384    fn begin_array_value<W: ?Sized>(&mut self, writer: &mut W, first: bool) -> Result<()>
385    where
386        W: Write,
387    {
388        if !first {
389            write!(writer, ",")?;
390        }
391
392        write!(writer, "\n{}", self.get_indentation())
393    }
394
395    fn begin_object_key<W: ?Sized>(&mut self, writer: &mut W, first: bool) -> Result<()>
396    where
397        W: Write,
398    {
399        if !first {
400            write!(writer, ",")?;
401        }
402
403        self.current_is_key = true;
404
405        write!(writer, "\n{}", self.get_indentation())
406    }
407
408    fn end_object_key<W: ?Sized>(&mut self, _writer: &mut W) -> Result<()>
409    where
410        W: Write,
411    {
412        self.current_is_key = false;
413        Ok(())
414    }
415
416    fn begin_object_value<W: ?Sized>(&mut self, writer: &mut W) -> Result<()>
417    where
418        W: Write,
419    {
420        write!(writer, ": ")
421    }
422
423    fn begin_object<W: ?Sized>(&mut self, writer: &mut W) -> Result<()>
424    where
425        W: Write,
426    {
427        self.indent_level += 1;
428        write!(writer, "{{")
429    }
430
431    fn end_object<W: ?Sized>(&mut self, writer: &mut W) -> Result<()>
432    where
433        W: Write,
434    {
435        self.indent_level -= 1;
436        write!(writer, "\n{}}}", self.get_indentation())
437    }
438}