1use core::num::FpCategory;
2use serde::Serialize;
3use serde_json::{
4 ser::{CharEscape, CompactFormatter, Formatter},
5 Result, Serializer,
6};
7
8use std::io::{self, Error, ErrorKind, Write};
9
10use crate::object::ObjectStack;
11
12#[inline]
20pub fn to_string<T>(value: &T) -> Result<String>
21where
22 T: Serialize + ?Sized,
23{
24 let data: Vec<u8> = to_vec(value)?;
25
26 let data: String = unsafe { String::from_utf8_unchecked(data) };
27
28 Ok(data)
29}
30
31#[inline]
39pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
40where
41 T: Serialize + ?Sized,
42{
43 let mut data: Vec<u8> = Vec::with_capacity(128);
44
45 to_writer(&mut data, value)?;
46
47 Ok(data)
48}
49
50#[inline]
58pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
59where
60 W: Write,
61 T: Serialize + ?Sized,
62{
63 value.serialize(&mut Serializer::with_formatter(
64 writer,
65 CanonicalFormatter::new(),
66 ))
67}
68
69static MAX_SAFE_INTEGER_U64: u64 = 9_007_199_254_740_991;
70static MAX_SAFE_INTEGER_I64: i64 = 9_007_199_254_740_991;
71static MAX_SAFE_INTEGER_U128: u128 = 9_007_199_254_740_991;
72static MAX_SAFE_INTEGER_I128: i128 = 9_007_199_254_740_991;
73
74#[derive(Clone, Debug)]
75#[repr(transparent)]
76pub struct CanonicalFormatter {
77 stack: ObjectStack,
78}
79
80impl CanonicalFormatter {
81 pub fn new() -> Self {
82 Self {
83 stack: ObjectStack::new(),
84 }
85 }
86}
87
88impl Formatter for CanonicalFormatter {
89 #[inline]
91 fn write_null<W>(&mut self, writer: &mut W) -> io::Result<()>
92 where
93 W: Write + ?Sized,
94 {
95 let mut writer = self.stack.scope(writer)?;
96 writer.write_all(b"null")?;
97 Ok(())
98 }
99
100 #[inline]
102 fn write_bool<W>(&mut self, writer: &mut W, value: bool) -> io::Result<()>
103 where
104 W: Write + ?Sized,
105 {
106 let mut writer = self.stack.scope(writer)?;
107 if value {
108 writer.write_all(b"true")?;
109 } else {
110 writer.write_all(b"false")?;
111 }
112 Ok(())
113 }
114
115 #[inline]
117 fn write_i8<W>(&mut self, writer: &mut W, value: i8) -> io::Result<()>
118 where
119 W: Write + ?Sized,
120 {
121 CompactFormatter.write_i8(&mut self.stack.scope_with_key(writer)?, value)
122 }
123
124 #[inline]
126 fn write_i16<W>(&mut self, writer: &mut W, value: i16) -> io::Result<()>
127 where
128 W: Write + ?Sized,
129 {
130 CompactFormatter.write_i16(&mut self.stack.scope_with_key(writer)?, value)
131 }
132
133 #[inline]
135 fn write_i32<W>(&mut self, writer: &mut W, value: i32) -> io::Result<()>
136 where
137 W: Write + ?Sized,
138 {
139 CompactFormatter.write_i32(&mut self.stack.scope_with_key(writer)?, value)
140 }
141
142 #[inline]
146 fn write_i64<W>(&mut self, writer: &mut W, value: i64) -> io::Result<()>
147 where
148 W: Write + ?Sized,
149 {
150 if self.stack.is_in_key()? {
151 CompactFormatter.write_i64(&mut self.stack.scope_with_key(writer)?, value)
152 } else {
153 if value.abs() > MAX_SAFE_INTEGER_I64 {
154 Err(Error::new(
155 ErrorKind::InvalidData,
156 "i64.abs() must be less than JSON max safe integer",
157 ))
158 } else {
159 CompactFormatter.write_i64(&mut self.stack.scope(writer)?, value)
160 }
161 }
162 }
163
164 #[inline]
168 fn write_i128<W>(&mut self, writer: &mut W, value: i128) -> io::Result<()>
169 where
170 W: Write + ?Sized,
171 {
172 if self.stack.is_in_key()? {
173 CompactFormatter.write_i128(&mut self.stack.scope_with_key(writer)?, value)
174 } else {
175 if value.abs() > MAX_SAFE_INTEGER_I128 {
176 Err(Error::new(
177 ErrorKind::InvalidData,
178 "i128.abs() must be less than JSON max safe integer",
179 ))
180 } else {
181 CompactFormatter.write_i128(&mut self.stack.scope(writer)?, value)
182 }
183 }
184 }
185
186 #[inline]
188 fn write_u8<W>(&mut self, writer: &mut W, value: u8) -> io::Result<()>
189 where
190 W: Write + ?Sized,
191 {
192 CompactFormatter.write_u8(&mut self.stack.scope_with_key(writer)?, value)
193 }
194
195 #[inline]
197 fn write_u16<W>(&mut self, writer: &mut W, value: u16) -> io::Result<()>
198 where
199 W: Write + ?Sized,
200 {
201 CompactFormatter.write_u16(&mut self.stack.scope_with_key(writer)?, value)
202 }
203
204 #[inline]
206 fn write_u32<W>(&mut self, writer: &mut W, value: u32) -> io::Result<()>
207 where
208 W: Write + ?Sized,
209 {
210 CompactFormatter.write_u32(&mut self.stack.scope_with_key(writer)?, value)
211 }
212
213 #[inline]
217 fn write_u64<W>(&mut self, writer: &mut W, value: u64) -> io::Result<()>
218 where
219 W: Write + ?Sized,
220 {
221 if self.stack.is_in_key()? {
222 CompactFormatter.write_u64(&mut self.stack.scope_with_key(writer)?, value)
223 } else {
224 if value > MAX_SAFE_INTEGER_U64 {
225 Err(Error::new(
226 ErrorKind::InvalidData,
227 "u64 must be less than JSON max safe integer",
228 ))
229 } else {
230 CompactFormatter.write_u64(&mut self.stack.scope(writer)?, value)
231 }
232 }
233 }
234
235 #[inline]
239 fn write_u128<W>(&mut self, writer: &mut W, value: u128) -> io::Result<()>
240 where
241 W: Write + ?Sized,
242 {
243 if self.stack.is_in_key()? {
244 CompactFormatter.write_u128(&mut self.stack.scope_with_key(writer)?, value)
245 } else {
246 if value > MAX_SAFE_INTEGER_U128 {
247 Err(Error::new(
248 ErrorKind::InvalidData,
249 "u128 must be less than JSON max safe integer",
250 ))
251 } else {
252 CompactFormatter.write_u128(&mut self.stack.scope(writer)?, value)
253 }
254 }
255 }
256
257 #[inline]
263 fn write_f32<W>(&mut self, writer: &mut W, value: f32) -> io::Result<()>
264 where
265 W: Write + ?Sized,
266 {
267 write_float(
268 &mut self.stack.scope_with_key(writer)?,
269 value.classify(),
270 value,
271 )
272 }
273
274 #[inline]
280 fn write_f64<W>(&mut self, writer: &mut W, value: f64) -> io::Result<()>
281 where
282 W: Write + ?Sized,
283 {
284 write_float(
285 &mut self.stack.scope_with_key(writer)?,
286 value.classify(),
287 value,
288 )
289 }
290
291 #[inline]
293 fn write_number_str<W>(&mut self, writer: &mut W, value: &str) -> io::Result<()>
294 where
295 W: Write + ?Sized,
296 {
297 let bytes = value.as_bytes();
298 let mut writer = self.stack.scope_with_key(writer)?;
299 writer.write_all(bytes)?;
300 Ok(())
301 }
302
303 #[inline]
307 fn begin_string<W>(&mut self, writer: &mut W) -> io::Result<()>
308 where
309 W: Write + ?Sized,
310 {
311 CompactFormatter.begin_string(&mut self.stack.scope(writer)?)
312 }
313
314 #[inline]
318 fn end_string<W>(&mut self, writer: &mut W) -> io::Result<()>
319 where
320 W: Write + ?Sized,
321 {
322 CompactFormatter.end_string(&mut self.stack.scope(writer)?)
323 }
324
325 #[inline]
327 fn write_string_fragment<W>(&mut self, writer: &mut W, fragment: &str) -> io::Result<()>
328 where
329 W: Write + ?Sized,
330 {
331 let bytes = fragment.as_bytes();
332 let mut writer = self.stack.scope_with_key(writer)?;
333 writer.write_all(bytes)?;
334 Ok(())
335 }
336
337 #[inline]
339 fn write_char_escape<W>(&mut self, writer: &mut W, escape: CharEscape) -> io::Result<()>
340 where
341 W: Write + ?Sized,
342 {
343 static HEX_CHARS: [u8; 16] = *b"0123456789abcdef";
344
345 match escape {
346 CharEscape::Backspace => {
347 self.stack.key_bytes()?.write_all(&[0x08])?;
348 self.stack.scope(writer)?.write_all(b"\\b")?;
349 }
350 CharEscape::Tab => {
351 self.stack.key_bytes()?.write_all(&[0x09])?;
352 self.stack.scope(writer)?.write_all(b"\\t")?;
353 }
354 CharEscape::LineFeed => {
355 self.stack.key_bytes()?.write_all(&[0x0A])?;
356 self.stack.scope(writer)?.write_all(b"\\n")?;
357 }
358 CharEscape::FormFeed => {
359 self.stack.key_bytes()?.write_all(&[0x0C])?;
360 self.stack.scope(writer)?.write_all(b"\\f")?;
361 }
362 CharEscape::CarriageReturn => {
363 self.stack.key_bytes()?.write_all(&[0x0D])?;
364 self.stack.scope(writer)?.write_all(b"\\r")?;
365 }
366 CharEscape::Quote => {
367 self.stack.key_bytes()?.write_all(&[0x22])?;
368 self.stack.scope(writer)?.write_all(b"\\\"")?;
369 }
370 CharEscape::Solidus => {
371 self.stack.key_bytes()?.write_all(&[0x2F])?;
372 self.stack.scope(writer)?.write_all(b"\\/")?;
373 }
374 CharEscape::ReverseSolidus => {
375 self.stack.key_bytes()?.write_all(&[0x5C])?;
376 self.stack.scope(writer)?.write_all(b"\\\\")?;
377 }
378 CharEscape::AsciiControl(control) => {
379 self.stack.key_bytes()?.write_all(&[control])?;
380 self.stack.scope(writer)?.write_all(&[
381 b'\\',
382 b'u',
383 b'0',
384 b'0',
385 HEX_CHARS[(control >> 4) as usize],
386 HEX_CHARS[(control & 0xF) as usize],
387 ])?;
388 }
389 }
390 Ok(())
391 }
392
393 #[inline]
395 fn begin_array<W>(&mut self, writer: &mut W) -> io::Result<()>
396 where
397 W: Write + ?Sized,
398 {
399 CompactFormatter.begin_array(&mut self.stack.scope(writer)?)
400 }
401
402 #[inline]
404 fn end_array<W>(&mut self, writer: &mut W) -> io::Result<()>
405 where
406 W: Write + ?Sized,
407 {
408 CompactFormatter.end_array(&mut self.stack.scope(writer)?)
409 }
410
411 #[inline]
413 fn begin_array_value<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
414 where
415 W: Write + ?Sized,
416 {
417 CompactFormatter.begin_array_value(&mut self.stack.scope(writer)?, first)
418 }
419
420 #[inline]
422 fn end_array_value<W>(&mut self, writer: &mut W) -> io::Result<()>
423 where
424 W: Write + ?Sized,
425 {
426 CompactFormatter.end_array_value(&mut self.stack.scope(writer)?)
427 }
428
429 #[inline]
431 fn begin_object<W>(&mut self, _writer: &mut W) -> io::Result<()>
432 where
433 W: Write + ?Sized,
434 {
435 self.stack.start_object();
436 Ok(())
437 }
438
439 #[inline]
441 fn end_object<W>(&mut self, writer: &mut W) -> io::Result<()>
442 where
443 W: Write + ?Sized,
444 {
445 self.stack.end_object(writer)
446 }
447
448 #[inline]
450 fn begin_object_key<W>(&mut self, _writer: &mut W, _first: bool) -> io::Result<()>
451 where
452 W: Write + ?Sized,
453 {
454 self.stack.start_key()
455 }
456
457 #[inline]
459 fn end_object_key<W>(&mut self, _writer: &mut W) -> io::Result<()>
460 where
461 W: Write + ?Sized,
462 {
463 self.stack.end_key()
464 }
465
466 #[inline]
468 fn begin_object_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
469 where
470 W: Write + ?Sized,
471 {
472 Ok(())
473 }
474
475 #[inline]
477 fn end_object_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
478 where
479 W: Write + ?Sized,
480 {
481 Ok(())
482 }
483
484 #[inline]
486 fn write_raw_fragment<W>(&mut self, writer: &mut W, fragment: &str) -> io::Result<()>
487 where
488 W: Write + ?Sized,
489 {
490 let bytes = fragment.as_bytes();
491 let mut writer = self.stack.scope_with_key(writer)?;
492 writer.write_all(bytes)?;
493 Ok(())
494 }
495}
496
497fn write_float<W, F>(writer: &mut W, category: FpCategory, value: F) -> io::Result<()>
498where
499 W: Write + ?Sized,
500 F: ryu_js::Float,
501{
502 match category {
503 FpCategory::Nan => Err(Error::new(ErrorKind::InvalidData, "NaN is not allowed.")),
504 FpCategory::Infinite => Err(Error::new(
505 ErrorKind::InvalidData,
506 "Infinity is not allowed.",
507 )),
508 FpCategory::Zero => writer.write_all(b"0"),
509 FpCategory::Normal | FpCategory::Subnormal => {
510 writer.write_all(ryu_js::Buffer::new().format_finite(value).as_bytes())
511 }
512 }
513}