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
11pub trait DebugToJson
60{ fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result;
61
62 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}