nop_json/
debug_to_json.rs

1pub use nop_json_derive::*;
2use crate::nop_json::{number_to_string, READER_BUFFER_SIZE};
3use crate::value::Value;
4use crate::escape::escape;
5
6use std::{char, fmt, f32, f64};
7use std::collections::{HashMap, HashSet, BTreeMap, BTreeSet, LinkedList, VecDeque};
8use numtoa::NumToA;
9
10
11/// Trait that can be automatically derived for structs and enums. When it's derived, a [Debug](https://doc.rust-lang.org/std/fmt/trait.Debug.html) implementation is also added,
12/// so the object can be printed with `println!`.
13///
14/// Example:
15///
16/// ```
17/// use nop_json::DebugToJson;
18///
19/// #[derive(DebugToJson)]
20/// struct Point {x: i32, y: i32}
21///
22/// let point = Point {x: 1, y: 2};
23/// println!("{:?}", point);
24/// ```
25///
26/// Here is what automatic implementation expands to. If you write:
27///
28/// ```
29/// use nop_json::DebugToJson;
30///
31/// #[derive(DebugToJson)]
32/// struct Point {x: i32, y: i32}
33/// ```
34///
35/// The implementation will be:
36///
37/// ```
38/// use nop_json::DebugToJson;
39///
40/// struct Point {x: i32, y: i32}
41///
42/// impl DebugToJson for Point
43/// {	fn fmt(&self, out: &mut std::fmt::Formatter) -> std::fmt::Result
44/// 	{	write!(out, "{{\"x\":")?;
45/// 		DebugToJson::fmt(&self.x, out)?;
46/// 		write!(out, ",\"y\":")?;
47/// 		DebugToJson::fmt(&self.y, out)?;
48/// 		write!(out, "}}")
49/// 	}
50/// }
51/// impl std::fmt::Debug for Point
52/// {	fn fmt(&self, out: &mut std::fmt::Formatter) -> std::fmt::Result
53/// 	{	DebugToJson::fmt(self, out)
54/// 	}
55/// }
56/// ```
57///
58/// For more information, see [main page](index.html).
59pub trait DebugToJson
60{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result;
61
62	/// Any type that implements `DebugToJson` can be converted to JSON string. For example `DebugToJson` is implemented for primitive types:
63	/// ```
64	/// use nop_json::DebugToJson;
65	///
66	/// let smth = true;
67	/// assert_eq!(smth.to_json_string(), "true".to_string());
68	/// ```
69	/// For custom types:
70	/// ```
71	/// use nop_json::DebugToJson;
72	///
73	/// #[derive(DebugToJson)]
74	/// struct Something {value: i32}
75	///
76	/// let smth = Something {value: 123};
77	/// assert_eq!(smth.to_json_string(), "{\"value\":123}".to_string());
78	/// ```
79	fn to_json_string(&self) -> String where Self: std::marker::Sized
80	{	struct Wrapper<'a, T: DebugToJson>
81		{	value: &'a T
82		}
83		impl<'a, T: DebugToJson> fmt::Display for Wrapper<'a, T>
84		{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
85			{	DebugToJson::fmt(self.value, out)
86			}
87		}
88		let w = Wrapper {value: self};
89		w.to_string()
90	}
91}
92
93impl DebugToJson for ()
94{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
95	{	write!(out, "null")
96	}
97}
98
99impl DebugToJson for isize {fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {write!(out, "{}", self)}}
100impl DebugToJson for i128  {fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {write!(out, "{}", self)}}
101impl DebugToJson for i64   {fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {write!(out, "{}", self)}}
102impl DebugToJson for i32   {fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {write!(out, "{}", self)}}
103impl DebugToJson for i16   {fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {write!(out, "{}", self)}}
104impl DebugToJson for i8    {fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {write!(out, "{}", self)}}
105impl DebugToJson for usize {fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {write!(out, "{}", self)}}
106impl DebugToJson for u128  {fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {write!(out, "{}", self)}}
107impl DebugToJson for u64   {fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {write!(out, "{}", self)}}
108impl DebugToJson for u32   {fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {write!(out, "{}", self)}}
109impl DebugToJson for u16   {fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {write!(out, "{}", self)}}
110impl DebugToJson for u8    {fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {write!(out, "{}", self)}}
111
112impl DebugToJson for f64
113{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
114	{	if *self == f64::INFINITY
115		{	write!(out, "Infinity")
116		}
117		else if *self == f64::NEG_INFINITY
118		{	write!(out, "-Infinity")
119		}
120		else if *self == f64::NAN
121		{	write!(out, "\"NaN\"")
122		}
123		else
124		{	write!(out, "{}", self)
125		}
126	}
127}
128impl DebugToJson for f32
129{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
130	{	if *self == f32::INFINITY
131		{	write!(out, "\"Infinity\"")
132		}
133		else if *self == f32::NEG_INFINITY
134		{	write!(out, "\"-Infinity\"")
135		}
136		else if *self == f32::NAN
137		{	write!(out, "\"NaN\"")
138		}
139		else
140		{	write!(out, "{}", self)
141		}
142	}
143}
144
145impl DebugToJson for bool
146{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
147	{	write!(out, "{}", if *self {"true"} else {"false"})
148	}
149}
150
151impl DebugToJson for char
152{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
153	{	match *self
154		{	'"' => write!(out, stringify!("\"")),
155			'\\' => write!(out, stringify!("\\")),
156			_ => write!(out, "\"{}\"", self),
157		}
158	}
159}
160
161impl DebugToJson for String
162{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
163	{	write!(out, "\"{}\"", escape(&self))
164	}
165}
166
167impl DebugToJson for Value
168{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
169	{	match *self
170		{	Value::Null => write!(out, "null"),
171			Value::Bool(v) => if v {write!(out, "true")} else {write!(out, "false")},
172			Value::Number(mantissa, exponent, is_negative) =>
173			{	let mut buffer = [0u8; 24];
174				let mantissa = mantissa.numtoa(10, &mut buffer);
175				let mut buffer = [0u8; READER_BUFFER_SIZE];
176				&mut buffer[0 .. mantissa.len()].copy_from_slice(&mantissa);
177				let len = number_to_string(&mut buffer, mantissa.len(), exponent, is_negative).map_err(|_| fmt::Error {})?;
178				write!(out, "{}", String::from_utf8_lossy(&buffer[0 .. len]))
179			},
180			Value::String(ref v) => write!(out, "\"{}\"", escape(v)),
181			Value::Array(ref v) =>
182			{	let mut c = '[';
183				for item in v
184				{	write!(out, "{}", c)?;
185					DebugToJson::fmt(item, out)?;
186					c = ',';
187				}
188				if c == '['
189				{	write!(out, "[]")
190				}
191				else
192				{	write!(out, "]")
193				}
194			}
195			Value::Object(ref v) =>
196			{	let mut c = '{';
197				for (key, item) in v
198				{	write!(out, "{}\"{}\":", c, escape(key))?;
199					DebugToJson::fmt(item, out)?;
200					c = ',';
201				}
202				if c == '{'
203				{	write!(out, "{{}}")
204				}
205				else
206				{	write!(out, "}}")
207				}
208			}
209		}
210	}
211}
212
213impl<T> DebugToJson for Box<T> where T: DebugToJson
214{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
215	{	let v: &T = &*self;
216		DebugToJson::fmt(v, out)
217	}
218}
219
220impl<T> DebugToJson for std::sync::RwLock<T> where T: DebugToJson
221{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
222	{	match self.read()
223		{	Ok(v) => DebugToJson::fmt(&*v, out),
224			Err(_e) => Err(fmt::Error {})
225		}
226	}
227}
228
229impl<T> DebugToJson for std::sync::Mutex<T> where T: DebugToJson
230{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
231	{	match self.lock()
232		{	Ok(v) => DebugToJson::fmt(&*v, out),
233			Err(_e) => Err(fmt::Error {})
234		}
235	}
236}
237
238impl<T> DebugToJson for std::rc::Rc<T> where T: DebugToJson
239{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
240	{	let v: &T = &*self;
241		DebugToJson::fmt(v, out)
242	}
243}
244
245impl<T> DebugToJson for std::sync::Arc<T> where T: DebugToJson
246{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
247	{	let v: &T = &*self;
248		DebugToJson::fmt(v, out)
249	}
250}
251
252impl<T> DebugToJson for Option<T> where T: DebugToJson
253{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
254	{	match *self
255		{	Some(ref v) => DebugToJson::fmt(v, out),
256			None => write!(out, "null"),
257		}
258	}
259}
260
261impl<T> DebugToJson for Vec<T> where T: DebugToJson
262{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
263	{	let mut c = '[';
264		for item in self
265		{	write!(out, "{}", c)?;
266			DebugToJson::fmt(item, out)?;
267			c = ',';
268		}
269		if c == '['
270		{	write!(out, "[]")
271		}
272		else
273		{	write!(out, "]")
274		}
275	}
276}
277
278impl<T> DebugToJson for HashSet<T> where T: DebugToJson
279{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
280	{	let mut c = '[';
281		for item in self
282		{	write!(out, "{}", c)?;
283			DebugToJson::fmt(item, out)?;
284			c = ',';
285		}
286		if c == '['
287		{	write!(out, "[]")
288		}
289		else
290		{	write!(out, "]")
291		}
292	}
293}
294
295impl<T> DebugToJson for LinkedList<T> where T: DebugToJson
296{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
297	{	let mut c = '[';
298		for item in self
299		{	write!(out, "{}", c)?;
300			DebugToJson::fmt(item, out)?;
301			c = ',';
302		}
303		if c == '['
304		{	write!(out, "[]")
305		}
306		else
307		{	write!(out, "]")
308		}
309	}
310}
311
312impl<T> DebugToJson for VecDeque<T> where T: DebugToJson
313{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
314	{	let mut c = '[';
315		for item in self
316		{	write!(out, "{}", c)?;
317			DebugToJson::fmt(item, out)?;
318			c = ',';
319		}
320		if c == '['
321		{	write!(out, "[]")
322		}
323		else
324		{	write!(out, "]")
325		}
326	}
327}
328
329impl<T> DebugToJson for BTreeSet<T> where T: DebugToJson
330{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
331	{	let mut c = '[';
332		for item in self
333		{	write!(out, "{}", c)?;
334			DebugToJson::fmt(item, out)?;
335			c = ',';
336		}
337		if c == '['
338		{	write!(out, "[]")
339		}
340		else
341		{	write!(out, "]")
342		}
343	}
344}
345
346impl<T> DebugToJson for HashMap<String, T> where T: DebugToJson
347{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
348	{	let mut c = '{';
349		for (key, item) in self
350		{	write!(out, "{}\"{}\":", c, escape(key))?;
351			DebugToJson::fmt(item, out)?;
352			c = ',';
353		}
354		if c == '{'
355		{	write!(out, "{{}}")
356		}
357		else
358		{	write!(out, "}}")
359		}
360	}
361}
362
363impl<T> DebugToJson for BTreeMap<String, T> where T: DebugToJson
364{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
365	{	let mut c = '{';
366		for (key, item) in self
367		{	write!(out, "{}\"{}\":", c, escape(key))?;
368			DebugToJson::fmt(item, out)?;
369			c = ',';
370		}
371		if c == '{'
372		{	write!(out, "{{}}")
373		}
374		else
375		{	write!(out, "}}")
376		}
377	}
378}
379
380impl<A, B> DebugToJson for (A, B) where A: DebugToJson, B: DebugToJson
381{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
382	{	write!(out, "[")?;
383		DebugToJson::fmt(&self.0, out)?;
384		write!(out, ",")?;
385		DebugToJson::fmt(&self.1, out)?;
386		write!(out, "]")
387	}
388}
389
390impl<A, B, C> DebugToJson for (A, B, C) where A: DebugToJson, B: DebugToJson, C: DebugToJson
391{	fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result
392	{	write!(out, "[")?;
393		DebugToJson::fmt(&self.0, out)?;
394		write!(out, ",")?;
395		DebugToJson::fmt(&self.1, out)?;
396		write!(out, ",")?;
397		DebugToJson::fmt(&self.2, out)?;
398		write!(out, "]")
399	}
400}