deser_json/ser.rs
1use alloc::boxed::Box;
2use alloc::string::String;
3use alloc::string::ToString;
4use alloc::vec::Vec;
5use core::mem::ManuallyDrop;
6
7use deser_core::__format::IntBuffer;
8use deser_core::ext::{BigInt, Decimal, ExtValue, Number};
9use deser_core::ser::{self, PausableSink, SerializeDriver, Written};
10use deser_core::{Atom, BytesFormat, Error, ErrorKind, Event, Implicit, ImplicitValue, Serialize};
11
12use crate::Trailing;
13use crate::buf::Buffer;
14use crate::escape::find_escape;
15use crate::pretty::PrettyWriter;
16use crate::scan::skip_to_escape;
17
18/// How the output is indented.
19///
20/// See [`SerializerConfig::indent`] and [`SerializerConfig::pretty`].
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
22#[non_exhaustive]
23pub enum Indent {
24 /// No indentation, the value is written on a single line.
25 #[default]
26 None,
27 /// Every entry on a line of its own, indented by the given number of
28 /// spaces per level.
29 Spaces(usize),
30 /// Every entry on a line of its own, indented by a tab per level.
31 Tab,
32}
33
34/// When maps and sequences are written on a single line in indented
35/// output.
36///
37/// Maps and sequences with the [`Layout::Compact`](deser_core::hints::Layout)
38/// hint are always written on a single line, the ones with
39/// [`Layout::Expanded`](deser_core::hints::Layout) never (unless they are in a
40/// map or sequence on a single line). See [`SerializerConfig::inline`].
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
42#[non_exhaustive]
43pub enum InlinePolicy {
44 /// Only compact maps and sequences are written on a single line.
45 #[default]
46 Never,
47 /// Maps and sequences which only contain scalars (no maps or
48 /// sequences, not even empty ones) are written on a single line if
49 /// that line is not longer than the given number of characters
50 /// (including the indentation, a tab counts as one character).
51 LeafIfFits(usize),
52}
53
54/// Configures how values are serialized to JSON.
55///
56/// By default the output is as short as possible: no line breaks and no
57/// spaces. [`pretty`](Self::pretty) writes every entry on a line of its
58/// own:
59///
60/// ```
61/// use std::collections::BTreeMap;
62/// use deser_json::{Indent, SerializerConfig};
63///
64/// let value = BTreeMap::from([("name", vec!["a", "b"])]);
65/// assert_eq!(
66/// deser_json::to_string(&value).unwrap(),
67/// r#"{"name":["a","b"]}"#
68/// );
69///
70/// const PRETTY: SerializerConfig =
71/// SerializerConfig::new().pretty(Indent::Spaces(2));
72/// assert_eq!(
73/// PRETTY.to_string(&value).unwrap(),
74/// "{\n \"name\": [\n \"a\",\n \"b\"\n ]\n}"
75/// );
76/// ```
77///
78/// In indented output maps and sequences with the
79/// [`Layout::Compact`](deser_core::hints::Layout) hint (see
80/// [`hints`](deser_core::hints)) are written on a single line. The output never
81/// ends with a line break.
82///
83/// [`to_string`](Self::to_string) works like the
84/// [`to_string`](crate::to_string) function.
85#[derive(Debug, Clone, PartialEq, Eq)]
86pub struct SerializerConfig {
87 bytes: BytesFormat,
88 indent: Indent,
89 compact: bool,
90 inline: InlinePolicy,
91 trailing: Trailing,
92}
93
94impl Default for SerializerConfig {
95 fn default() -> SerializerConfig {
96 SerializerConfig::new()
97 }
98}
99
100impl SerializerConfig {
101 /// Creates the default configuration.
102 pub const fn new() -> SerializerConfig {
103 SerializerConfig {
104 bytes: BytesFormat::BASE64,
105 indent: Indent::None,
106 compact: true,
107 inline: InlinePolicy::Never,
108 trailing: Trailing::Strict,
109 }
110 }
111
112 /// Sets what follows the values of a stream.
113 ///
114 /// This is the counterpart of
115 /// [`DeserializerConfig::trailing`](crate::DeserializerConfig::trailing)
116 /// for writing more than one value (with a [`Serializer`] or a stream
117 /// writer), it does not affect [`to_string`](Self::to_string):
118 ///
119 /// * [`Trailing::Strict`]: the stream holds a single value, writing a
120 /// second one fails. This is the default.
121 /// * [`Trailing::Newline`]: every value is followed by a line break
122 /// ([JSON Lines](https://jsonlines.org/)). The values must not be
123 /// indented.
124 /// * [`Trailing::Stop`]: values are separated by line breaks.
125 ///
126 /// ```
127 /// use deser_json::{Serializer, SerializerConfig, Trailing};
128 ///
129 /// const LINES: SerializerConfig =
130 /// SerializerConfig::new().trailing(Trailing::Newline);
131 /// let mut serializer = Serializer::with_config(&LINES);
132 /// serializer.serialize(&vec![1, 2]).unwrap();
133 /// serializer.serialize(&vec![3]).unwrap();
134 /// assert_eq!(serializer.finish(), "[1,2]\n[3]\n");
135 /// ```
136 pub const fn trailing(mut self, trailing: Trailing) -> SerializerConfig {
137 self.trailing = trailing;
138 self
139 }
140
141 /// Returns what follows the values of a stream.
142 pub(crate) fn trailing_mode(&self) -> Trailing {
143 self.trailing
144 }
145
146 /// Sets how the output is indented.
147 ///
148 /// By default ([`Indent::None`]) the value is written on a single line.
149 /// Otherwise every entry of a map or sequence is written on a line of
150 /// its own, indented by its depth. Empty maps and sequences are always
151 /// written as `{}` and `[]`. This does not change the spaces after
152 /// separators, see [`compact`](Self::compact). To indent with spaces
153 /// after separators use [`pretty`](Self::pretty).
154 ///
155 /// ```
156 /// use deser_json::{Indent, SerializerConfig};
157 ///
158 /// const TAB: SerializerConfig = SerializerConfig::new().indent(Indent::Tab);
159 /// assert_eq!(TAB.to_string(&vec![1, 2]).unwrap(), "[\n\t1,\n\t2\n]");
160 /// ```
161 pub const fn indent(mut self, indent: Indent) -> SerializerConfig {
162 self.indent = indent;
163 self
164 }
165
166 /// Controls the spaces after separators.
167 ///
168 /// When enabled (which is the default) there are no spaces after `:`
169 /// and `,`. When disabled a space follows every `:` and every `,`
170 /// that is not followed by a line break:
171 ///
172 /// ```
173 /// use std::collections::BTreeMap;
174 /// use deser_json::SerializerConfig;
175 ///
176 /// let value = BTreeMap::from([("a", vec![1, 2])]);
177 /// const SPACED: SerializerConfig = SerializerConfig::new().compact(false);
178 /// assert_eq!(SPACED.to_string(&value).unwrap(), r#"{"a": [1, 2]}"#);
179 /// ```
180 pub const fn compact(mut self, yes: bool) -> SerializerConfig {
181 self.compact = yes;
182 self
183 }
184
185 /// Sets when maps and sequences are written on a single line in
186 /// indented output.
187 ///
188 /// ```
189 /// use deser::Serialize;
190 /// use deser_json::{Indent, InlinePolicy, SerializerConfig};
191 ///
192 /// #[derive(Serialize)]
193 /// struct Shape {
194 /// name: &'static str,
195 /// points: Vec<Vec<i32>>,
196 /// }
197 ///
198 /// let shape = Shape {
199 /// name: "line",
200 /// points: vec![vec![0, 0], vec![3, 4]],
201 /// };
202 /// const CONFIG: SerializerConfig = SerializerConfig::new()
203 /// .pretty(Indent::Spaces(2))
204 /// .inline(InlinePolicy::LeafIfFits(80));
205 /// assert_eq!(CONFIG.to_string(&shape).unwrap(), r#"{
206 /// "name": "line",
207 /// "points": [
208 /// [0, 0],
209 /// [3, 4]
210 /// ]
211 /// }"#);
212 /// ```
213 ///
214 /// This has no effect without [indentation](Self::indent).
215 pub const fn inline(mut self, policy: InlinePolicy) -> SerializerConfig {
216 self.inline = policy;
217 self
218 }
219
220 /// Enables or disables pretty printing.
221 ///
222 /// This sets the [indentation](Self::indent) and writes spaces after
223 /// separators (see [`compact`](Self::compact)) unless the indentation
224 /// is [`Indent::None`], in which case the output is compact again.
225 ///
226 /// ```
227 /// use std::collections::BTreeMap;
228 /// use deser_json::{Indent, SerializerConfig};
229 ///
230 /// let value = BTreeMap::from([("a", 1)]);
231 /// const PRETTY: SerializerConfig =
232 /// SerializerConfig::new().pretty(Indent::Spaces(4));
233 /// assert_eq!(PRETTY.to_string(&value).unwrap(), "{\n \"a\": 1\n}");
234 /// const NOT_PRETTY: SerializerConfig = PRETTY.pretty(Indent::None);
235 /// assert_eq!(NOT_PRETTY.to_string(&value).unwrap(), r#"{"a":1}"#);
236 /// ```
237 pub const fn pretty(mut self, indent: Indent) -> SerializerConfig {
238 self.indent = indent;
239 self.compact = matches!(indent, Indent::None);
240 self
241 }
242
243 /// Sets how bytes are represented.
244 ///
245 /// JSON has no bytes, by default they are written as base64 strings
246 /// ([`BytesFormat::BASE64`]). Values can request a different format
247 /// (see [bytes](deser_core::adapters#bytes)) which takes precedence. Map keys cannot be
248 /// sequences, bytes in keys are always strings.
249 ///
250 /// ```
251 /// use deser::adapters::Base64UrlNoPad;
252 /// use deser::BytesFormat;
253 /// use deser_json::SerializerConfig;
254 ///
255 /// assert_eq!(deser_json::to_string(&b"\xfb\xff").unwrap(), r#""+/8=""#);
256 /// const URL_SAFE: SerializerConfig = SerializerConfig::new()
257 /// .bytes(BytesFormat::encoded::<Base64UrlNoPad>());
258 /// assert_eq!(URL_SAFE.to_string(&b"\xfb\xff").unwrap(), r#""-_8""#);
259 /// const SEQ: SerializerConfig =
260 /// SerializerConfig::new().bytes(BytesFormat::SEQ);
261 /// assert_eq!(SEQ.to_string(&b"\xfb\xff").unwrap(), "[251,255]");
262 /// ```
263 ///
264 /// More encodings (such as hex) are provided by
265 /// [`deser-encoding`](https://docs.rs/deser-encoding). Bytes in other
266 /// formats than base64 (or sequences) need to be
267 /// deserialized with the same format (see
268 /// [`DeserializerConfig::bytes`](crate::DeserializerConfig::bytes)).
269 pub const fn bytes(mut self, format: BytesFormat) -> SerializerConfig {
270 self.bytes = format;
271 self
272 }
273
274 /// Serializes the given value.
275 // inlined so that the pretty writer is not linked for constant compact
276 // configurations (see `serialize_driver`)
277 #[inline]
278 pub fn to_string(&self, value: &dyn Serialize) -> Result<String, Error> {
279 self.to_string_with(value, |_| {})
280 }
281
282 /// Serializes the given value with a configured driver.
283 ///
284 /// The callback is invoked with the driver before the serialization
285 /// starts, for instance to add [`Layer`](deser_core::ser::Layer)s.
286 ///
287 /// ```
288 /// use deser::ser::{Layer, Next};
289 /// use deser::{Atom, Error, Event};
290 /// use deser_json::SerializerConfig;
291 ///
292 /// /// Writes all numbers as strings.
293 /// struct NumbersAsStrings;
294 ///
295 /// impl Layer for NumbersAsStrings {
296 /// fn event(
297 /// &mut self,
298 /// event: Event<'_>,
299 /// next: &mut Next<'_>,
300 /// ) -> Result<(), Error> {
301 /// match event {
302 /// Event::Atom(Atom::U64(value)) => {
303 /// next.emit(value.to_string().into())
304 /// }
305 /// event => next.emit(event),
306 /// }
307 /// }
308 /// }
309 ///
310 /// let json = SerializerConfig::new()
311 /// .to_string_with(&vec![1u64, 2], |driver| {
312 /// driver.push_layer(NumbersAsStrings)
313 /// })
314 /// .unwrap();
315 /// assert_eq!(json, r#"["1","2"]"#);
316 /// ```
317 pub fn to_string_with<F>(&self, value: &dyn Serialize, setup: F) -> Result<String, Error>
318 where
319 F: FnOnce(&mut SerializeDriver<'_>),
320 {
321 let mut driver = SerializeDriver::new(value);
322 setup(&mut driver);
323 self.serialize_driver(&mut driver)
324 }
325
326 /// Serializes the value of a driver.
327 ///
328 /// This is inlined: if the configuration is a constant (like the one
329 /// of `to_string`) only the writer that is used ends up in the binary.
330 #[inline]
331 pub(crate) fn serialize_driver(
332 &self,
333 driver: &mut SerializeDriver<'_>,
334 ) -> Result<String, Error> {
335 if self.is_compact() {
336 self.serialize_compact(driver)
337 } else {
338 self.serialize_pretty(driver)
339 }
340 }
341
342 /// Returns `true` if the output is written by `Writer`.
343 #[inline(always)]
344 fn is_compact(&self) -> bool {
345 self.indent == Indent::None && self.compact
346 }
347
348 /// Serializes the value of a driver without indentation.
349 #[inline(never)]
350 fn serialize_compact(&self, driver: &mut SerializeDriver<'_>) -> Result<String, Error> {
351 let mut writer = self.compact_writer(Buffer::with_capacity(128));
352 driver.drive_sink(&mut writer)?;
353 Ok(writer.ser.out.into_string())
354 }
355
356 /// Serializes the value of a driver with the pretty writer.
357 #[inline(never)]
358 fn serialize_pretty(&self, driver: &mut SerializeDriver<'_>) -> Result<String, Error> {
359 let mut writer = self.pretty_writer(Buffer::with_capacity(128));
360 driver.drive(|event, state| writer.event(event, state))?;
361 Ok(writer.finish())
362 }
363
364 /// Creates the writer for compact output.
365 fn compact_writer(&self, out: Buffer) -> Writer {
366 Writer {
367 ser: Output {
368 out,
369 bytes: self.bytes,
370 },
371 stack: Vec::new(),
372 container: Container::Top,
373 first: true,
374 is_key: false,
375 limit: usize::MAX,
376 }
377 }
378
379 /// Creates the writer for everything but compact output.
380 fn pretty_writer(&self, out: Buffer) -> PrettyWriter {
381 let ser = Output {
382 out,
383 bytes: self.bytes,
384 };
385 let inline_width = match self.inline {
386 InlinePolicy::Never => None,
387 InlinePolicy::LeafIfFits(width) => Some(width),
388 };
389 PrettyWriter::new(ser, self.indent, self.compact, inline_width)
390 }
391
392 /// Creates the writer for a value which writes into the buffer.
393 pub(crate) fn value_writer(&self, out: Buffer) -> ValueWriter {
394 if self.is_compact() {
395 ValueWriter::Compact(self.compact_writer(out))
396 } else {
397 ValueWriter::Pretty(self.pretty_writer(out))
398 }
399 }
400}
401
402/// Writes the events of a value.
403pub(crate) enum ValueWriter {
404 /// Compact output (no indentation, no spaces).
405 Compact(Writer),
406 /// Everything else.
407 Pretty(PrettyWriter),
408}
409
410impl ValueWriter {
411 /// Writes the events of the driver.
412 ///
413 /// Returns `false` if the driver was paused as the output holds at
414 /// least `limit` bytes (see `take_output`). With a limit of
415 /// `usize::MAX` the value is written at once.
416 pub(crate) fn drive(
417 &mut self,
418 driver: &mut SerializeDriver<'_>,
419 limit: usize,
420 ) -> Result<bool, Error> {
421 if limit == usize::MAX {
422 return self.drive_whole(driver).map(|()| true);
423 }
424 match self {
425 ValueWriter::Compact(writer) => {
426 writer.limit = limit;
427 driver.drive_until(writer)
428 }
429 ValueWriter::Pretty(writer) => {
430 writer.limit = limit;
431 driver.drive_until(writer)
432 }
433 }
434 }
435
436 /// Writes the events of the driver at once.
437 ///
438 /// Unlike `drive` this does not refer to the pausable instances of the
439 /// driver which are only needed by stream serializers.
440 pub(crate) fn drive_whole(&mut self, driver: &mut SerializeDriver<'_>) -> Result<(), Error> {
441 match self {
442 ValueWriter::Compact(writer) => driver.drive_sink(writer),
443 ValueWriter::Pretty(writer) => driver.drive(|event, state| writer.event(event, state)),
444 }
445 }
446
447 /// Returns the output buffer.
448 pub(crate) fn output(&mut self) -> &mut Buffer {
449 match self {
450 ValueWriter::Compact(writer) => &mut writer.ser.out,
451 ValueWriter::Pretty(writer) => writer.output(),
452 }
453 }
454
455 /// Takes the output written so far (which is final after `drive`
456 /// returned), the writer continues with an empty output.
457 pub(crate) fn take_output(&mut self) -> Vec<u8> {
458 match self {
459 ValueWriter::Compact(writer) => writer.ser.out.take(),
460 ValueWriter::Pretty(writer) => writer.take_output(),
461 }
462 }
463}
464
465/// Serializes values into JSON.
466///
467/// Every call to [`serialize`](Self::serialize) writes a value. What
468/// follows the values depends on [`SerializerConfig::trailing`]: by default
469/// only a single value can be written, with [`Trailing::Newline`] every
470/// value is followed by a line break ([JSON Lines](https://jsonlines.org/)).
471///
472/// ```
473/// use deser_json::{Serializer, SerializerConfig, Trailing};
474///
475/// const LINES: SerializerConfig =
476/// SerializerConfig::new().trailing(Trailing::Newline);
477/// let mut serializer = Serializer::with_config(&LINES);
478/// serializer.serialize(&vec![1, 2]).unwrap();
479/// serializer.serialize(&"x").unwrap();
480/// assert_eq!(serializer.finish(), "[1,2]\n\"x\"\n");
481/// ```
482///
483/// The serializer is also the stream serializer of JSON (see
484/// [`StreamSerializer`](ser::StreamSerializer)): the output can be taken
485/// while values are written, and large values can be written in parts.
486/// To write to a [`Write`](std::io::Write) use
487/// [`SerializerConfig::writer`]:
488///
489/// ```
490/// # #[cfg(feature = "io")] {
491/// use deser_json::SerializerConfig;
492///
493/// let mut writer = SerializerConfig::new().writer(Vec::new());
494/// writer.set_buffer_limit(4);
495/// writer.write(&vec!["a", "b", "c"]).unwrap();
496/// assert_eq!(writer.into_inner(), br#"["a","b","c"]"#);
497/// # }
498/// ```
499pub struct Serializer {
500 config: SerializerConfig,
501 // only holds the output of value writers and line breaks, which is
502 // valid UTF-8
503 out: Vec<u8>,
504 written: usize,
505 // the value that is written in parts
506 value: Option<Box<ValueWriter>>,
507 // a value was started with `drive_partial` and is not complete
508 in_progress: bool,
509}
510
511impl Default for Serializer {
512 fn default() -> Serializer {
513 Serializer::new()
514 }
515}
516
517impl Clone for Serializer {
518 /// Clones the serializer.
519 ///
520 /// The clone of a serializer that writes a value in parts cannot write
521 /// more values (see
522 /// [`StreamSerializer::in_progress`](ser::StreamSerializer::in_progress)).
523 fn clone(&self) -> Serializer {
524 Serializer {
525 config: self.config.clone(),
526 out: self.out.clone(),
527 written: self.written,
528 value: None,
529 in_progress: self.in_progress,
530 }
531 }
532}
533
534impl core::fmt::Debug for Serializer {
535 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
536 f.debug_struct("Serializer")
537 .field("config", &self.config)
538 .field("output", &self.as_str())
539 .field("written", &self.written)
540 .field("in_progress", &self.in_progress)
541 .finish()
542 }
543}
544
545impl Serializer {
546 /// Creates a serializer.
547 pub fn new() -> Serializer {
548 Serializer::with_config(&SerializerConfig::new())
549 }
550
551 /// Creates a serializer with the given configuration.
552 pub fn with_config(config: &SerializerConfig) -> Serializer {
553 Serializer::with_written(config, 0)
554 }
555
556 /// Creates a serializer for a stream that continues after the given
557 /// number of values.
558 ///
559 /// This is useful to append to a stream that was written before (see
560 /// [`SerializerConfig::trailing`] for what separates the values).
561 pub fn with_written(config: &SerializerConfig, written: usize) -> Serializer {
562 Serializer {
563 config: config.clone(),
564 out: Vec::new(),
565 written,
566 value: None,
567 in_progress: false,
568 }
569 }
570
571 /// Returns the configuration.
572 pub fn config(&self) -> &SerializerConfig {
573 &self.config
574 }
575
576 /// Returns the number of values that were written.
577 pub fn written(&self) -> usize {
578 self.written
579 }
580
581 /// Serializes a value.
582 ///
583 /// If the value fails to serialize, nothing is written.
584 pub fn serialize(&mut self, value: &dyn Serialize) -> Result<(), Error> {
585 ser::Serializer::serialize(self, value)
586 }
587
588 /// Serializes a value with a configured driver.
589 ///
590 /// The callback is invoked with the driver before the value is
591 /// serialized, for instance to add [`Layer`](deser_core::ser::Layer)s.
592 pub fn serialize_with<F>(&mut self, value: &dyn Serialize, setup: F) -> Result<(), Error>
593 where
594 F: FnOnce(&mut SerializeDriver<'_>),
595 {
596 ser::Serializer::serialize_with(self, value, setup)
597 }
598
599 /// Returns the output written so far (that was not cleared).
600 pub fn as_str(&self) -> &str {
601 // SAFETY: the output is valid UTF-8, see `out`
602 unsafe { core::str::from_utf8_unchecked(&self.out) }
603 }
604
605 /// Returns the output.
606 pub fn finish(self) -> String {
607 // SAFETY: the output is valid UTF-8, see `out`
608 unsafe { String::from_utf8_unchecked(self.out) }
609 }
610
611 /// Starts a value: writes what separates it from the previous value.
612 fn start_value(&mut self) -> Result<(), Error> {
613 if self.in_progress {
614 return Err(Error::in_progress());
615 }
616 match self.config.trailing_mode() {
617 Trailing::Strict if self.written > 0 => Err(Error::new(
618 ErrorKind::Unexpected,
619 "with Trailing::Strict only a single value can be written",
620 )),
621 Trailing::Stop if self.written > 0 => {
622 self.out.push(b'\n');
623 Ok(())
624 }
625 _ => Ok(()),
626 }
627 }
628
629 /// Completes a value.
630 fn finish_value(&mut self) {
631 if self.config.trailing_mode() == Trailing::Newline {
632 self.out.push(b'\n');
633 }
634 self.written += 1;
635 self.in_progress = false;
636 }
637}
638
639impl ser::Serializer for Serializer {
640 fn drive(&mut self, driver: &mut SerializeDriver<'_>) -> Result<(), Error> {
641 // only `drive_partial` continues a value
642 if self.in_progress {
643 return Err(Error::in_progress());
644 }
645 ser::StreamSerializer::drive_partial(self, driver, usize::MAX).map(|_| ())
646 }
647}
648
649impl ser::StreamSerializer for Serializer {
650 fn output(&self) -> &[u8] {
651 &self.out
652 }
653
654 fn clear_output(&mut self) {
655 self.out.clear();
656 }
657
658 fn supports_partial(&self) -> bool {
659 true
660 }
661
662 fn drive_partial(
663 &mut self,
664 driver: &mut SerializeDriver<'_>,
665 limit: usize,
666 ) -> Result<Written, Error> {
667 let rollback = self.out.len();
668 let (mut local, adopt) = match self.value.take() {
669 // the writer writes into the output directly if it's empty,
670 // otherwise its output is appended
671 Some(mut writer) => {
672 let adopt = self.out.is_empty();
673 if adopt {
674 *writer.output() = Buffer::from_vec(core::mem::take(&mut self.out));
675 }
676 (writer, adopt)
677 }
678 None => {
679 self.start_value()?;
680 // a writer that completes the value at once is not boxed
681 let out = Buffer::from_vec(core::mem::take(&mut self.out));
682 let writer = self.config.value_writer(out);
683 if limit == usize::MAX {
684 return self.drive_whole(writer, driver, rollback);
685 }
686 (Box::new(writer), true)
687 }
688 };
689 let rv = local.drive(driver, limit);
690 match rv {
691 Ok(done) => {
692 let output = local.take_output();
693 if adopt {
694 self.out = output;
695 } else {
696 self.out.extend_from_slice(&output);
697 }
698 if done {
699 self.finish_value();
700 Ok(Written::Done)
701 } else {
702 self.value = Some(local);
703 self.in_progress = true;
704 Ok(Written::Partial)
705 }
706 }
707 Err(err) => {
708 // the value is abandoned, what was written of it is
709 // discarded. If parts of it were taken the stream stays
710 // broken (`in_progress`).
711 if adopt {
712 self.out = local.output().take();
713 self.out.truncate(rollback);
714 }
715 Err(err)
716 }
717 }
718 }
719
720 fn in_progress(&self) -> bool {
721 self.in_progress
722 }
723}
724
725impl Serializer {
726 /// Writes a value at once (see `drive_partial`).
727 fn drive_whole(
728 &mut self,
729 mut writer: ValueWriter,
730 driver: &mut SerializeDriver<'_>,
731 rollback: usize,
732 ) -> Result<Written, Error> {
733 let rv = writer.drive_whole(driver);
734 self.out = writer.output().take();
735 match rv {
736 Ok(_) => {
737 self.finish_value();
738 Ok(Written::Done)
739 }
740 Err(err) => {
741 self.out.truncate(rollback);
742 Err(err)
743 }
744 }
745 }
746}
747
748#[cfg(feature = "io")]
749impl SerializerConfig {
750 /// Creates a writer of a stream of values (see
751 /// [`deser::io::Writer`](deser_core::io::Writer)).
752 ///
753 /// What follows the values depends on [`trailing`](Self::trailing).
754 /// The output of large values is written in parts while they are
755 /// serialized.
756 ///
757 /// ```
758 /// use deser_json::{SerializerConfig, Trailing};
759 ///
760 /// const LINES: SerializerConfig =
761 /// SerializerConfig::new().trailing(Trailing::Newline);
762 /// let mut writer = LINES.writer(Vec::new());
763 /// writer.write(&1).unwrap();
764 /// writer.write(&"x").unwrap();
765 /// assert_eq!(writer.into_inner(), b"1\n\"x\"\n");
766 /// ```
767 pub fn writer<W: std::io::Write>(&self, writer: W) -> deser_core::io::Writer<W, Serializer> {
768 deser_core::io::Writer::new(writer, Serializer::with_config(self))
769 }
770
771 /// Serializes a value to a writer.
772 ///
773 /// See [`to_writer`](crate::to_writer).
774 pub fn to_writer<W: std::io::Write>(
775 &self,
776 writer: W,
777 value: &dyn Serialize,
778 ) -> Result<(), Error> {
779 self.writer(writer).write(value)
780 }
781}
782
783/// Serializes a value to a writer.
784///
785/// The output of large values is written in parts while they are
786/// serialized (see [`deser::io`](deser_core::io)), the writer does not
787/// need to be buffered.
788///
789/// ```
790/// let mut out = Vec::new();
791/// deser_json::to_writer(&mut out, &vec![1, 2, 3]).unwrap();
792/// assert_eq!(out, b"[1,2,3]");
793/// ```
794#[cfg(feature = "io")]
795pub fn to_writer<W: std::io::Write>(writer: W, value: &dyn Serialize) -> Result<(), Error> {
796 SerializerConfig::new().to_writer(writer, value)
797}
798
799/// The output of the serializer.
800pub(crate) struct Output {
801 pub(crate) out: Buffer,
802 bytes: BytesFormat,
803}
804
805#[derive(Clone, Copy, PartialEq, Eq)]
806enum Container {
807 Top,
808 Seq,
809 Map,
810}
811
812/// Holds the state of the serializer while writing.
813pub(crate) struct Writer {
814 ser: Output,
815 // the state of the current container is held here, the state of the
816 // outer containers is saved on the stack.
817 stack: Vec<Container>,
818 container: Container,
819 first: bool,
820 is_key: bool,
821 // the output is passed on once it's this long (see `PausableSink`)
822 limit: usize,
823}
824
825impl ser::EventSink for Writer {
826 #[inline(always)]
827 fn event(&mut self, event: Event, _state: &mut deser_core::State) -> Result<(), Error> {
828 Writer::event(self, event)
829 }
830}
831
832impl PausableSink for Writer {
833 #[inline(always)]
834 fn event(
835 &mut self,
836 event: Event<'_>,
837 _value: &dyn Serialize,
838 _state: &mut deser_core::State,
839 ) -> Result<(), Error> {
840 Writer::event(self, event)
841 }
842
843 #[inline(always)]
844 fn pause(&mut self) -> bool {
845 self.ser.out.len() >= self.limit
846 }
847}
848
849impl Writer {
850 #[inline(always)]
851 fn event(&mut self, event: Event) -> Result<(), Error> {
852 match event {
853 Event::Atom(atom) => {
854 if self.is_key {
855 self.ser.write_key_atom(atom, self.first)?;
856 self.is_key = false;
857 } else {
858 match self.container {
859 Container::Seq => {
860 if !self.first {
861 self.ser.write_char(',');
862 }
863 }
864 Container::Map => self.is_key = true,
865 Container::Top => {}
866 }
867 self.ser.write_atom(atom)?;
868 }
869 self.first = false;
870 Ok(())
871 }
872 Event::MapStart(_) => self.start(true),
873 Event::SeqStart(_) => self.start(false),
874 Event::MapEnd => self.end(true),
875 Event::SeqEnd => self.end(false),
876 }
877 }
878
879 #[inline]
880 fn start(&mut self, is_map: bool) -> Result<(), Error> {
881 if self.is_key {
882 return Err(Error::new(
883 ErrorKind::UnsupportedType,
884 "JSON does not support this value for map keys",
885 ));
886 }
887 if self.container == Container::Seq && !self.first {
888 self.ser.write_char(',');
889 }
890 self.stack.push(self.container);
891 self.first = true;
892 if is_map {
893 self.container = Container::Map;
894 self.is_key = true;
895 self.ser.write_char('{');
896 } else {
897 self.container = Container::Seq;
898 self.ser.write_char('[');
899 }
900 Ok(())
901 }
902
903 #[inline]
904 fn end(&mut self, is_map: bool) -> Result<(), Error> {
905 if is_map {
906 if self.container != Container::Map || !self.is_key {
907 return Err(Error::new(ErrorKind::Unexpected, "unexpected map end"));
908 }
909 self.ser.write_char('}');
910 } else {
911 if self.container != Container::Seq {
912 return Err(Error::new(ErrorKind::Unexpected, "unexpected array end"));
913 }
914 self.ser.write_char(']');
915 }
916 self.container = self.stack.pop().unwrap_or(Container::Top);
917 // a container is never a key, so after it the next item in a map is
918 // a key again.
919 self.first = false;
920 self.is_key = self.container == Container::Map;
921 Ok(())
922 }
923}
924
925impl Output {
926 /// Writes an atom in key position including separator and colon.
927 #[inline(always)]
928 fn write_key_atom(&mut self, atom: Atom, first: bool) -> Result<(), Error> {
929 // borrowed strings do not need to be dropped, the atom is only
930 // dropped for the other values.
931 let atom = ManuallyDrop::new(atom);
932 match *atom {
933 // fast path for the common case of string keys
934 Atom::Str(ref val) | Atom::Lexical(ref val) if val.is_borrowed() => {
935 self.write_key(val, first);
936 Ok(())
937 }
938 _ => self.write_other_key_atom(ManuallyDrop::into_inner(atom), first),
939 }
940 }
941
942 #[inline(never)]
943 fn write_other_key_atom(&mut self, atom: Atom, first: bool) -> Result<(), Error> {
944 if !first {
945 self.write_char(',');
946 }
947 self.write_key_text(atom)?;
948 self.write_char(':');
949 Ok(())
950 }
951
952 /// Writes an atom as map key without separator and colon.
953 pub(crate) fn write_key_text(&mut self, atom: Atom) -> Result<(), Error> {
954 match atom {
955 Atom::Str(ref val) | Atom::Lexical(ref val) => self.write_escaped_str(val),
956 Atom::Char(c) => self.write_escaped_str(c.encode_utf8(&mut [0u8; 4])),
957 Atom::U64(val) => {
958 self.write_char('"');
959 self.write_u64(val);
960 self.write_char('"');
961 }
962 Atom::I64(val) => {
963 self.write_char('"');
964 self.write_i64(val);
965 self.write_char('"');
966 }
967 Atom::Bool(val) => self.write_str(if val { "\"true\"" } else { "\"false\"" }),
968 Atom::Ext(ref ext) => self.write_ext_key(ext)?,
969 Atom::Bytes(ref val) => self.write_bytes_str(val, val.fallback),
970 Atom::Implicit(ref val) => match json_literal(val) {
971 Some(text) if val.value() != ImplicitValue::Null => self.write_escaped_str(text),
972 _ => return self.write_key_text(val.value().to_atom()),
973 },
974 _ => {
975 return Err(Error::new(
976 ErrorKind::UnsupportedType,
977 "JSON does not support this value for map keys",
978 ));
979 }
980 }
981 Ok(())
982 }
983
984 /// Writes an atom in value position.
985 #[inline(always)]
986 pub(crate) fn write_atom(&mut self, atom: Atom) -> Result<(), Error> {
987 // borrowed strings and scalars do not need to be dropped, the atom
988 // is only dropped for the other values.
989 let atom = ManuallyDrop::new(atom);
990 match *atom {
991 Atom::Null => self.write_str("null"),
992 Atom::Bool(true) => self.write_str("true"),
993 Atom::Bool(false) => self.write_str("false"),
994 Atom::Str(ref val) if val.is_borrowed() => self.write_escaped_str(val),
995 Atom::Char(c) => self.write_escaped_str(c.encode_utf8(&mut [0u8; 4])),
996 Atom::U64(val) => self.write_u64(val),
997 Atom::I64(val) => self.write_i64(val),
998 Atom::F64(val) => self.write_float(val),
999 Atom::F32(val) => self.write_float(val),
1000 _ => return self.write_other_atom(ManuallyDrop::into_inner(atom)),
1001 }
1002 Ok(())
1003 }
1004
1005 #[inline(never)]
1006 fn write_other_atom(&mut self, atom: Atom) -> Result<(), Error> {
1007 match atom {
1008 Atom::Str(ref val) | Atom::Lexical(ref val) => self.write_escaped_str(val),
1009 Atom::Ext(ref ext) => self.write_ext_value(ext)?,
1010 Atom::Bytes(ref val) => {
1011 self.write_bytes(val, val.fallback.copied().unwrap_or(self.bytes))
1012 }
1013 // values whose type was inferred from text keep their text if
1014 // it's the same value in JSON, otherwise they are written as
1015 // their value
1016 Atom::Implicit(ref val) => match json_literal(val) {
1017 Some(text) => self.write_str(text),
1018 None => return self.write_atom(val.value().to_atom()),
1019 },
1020 _ => return Err(Error::new(ErrorKind::UnsupportedType, "unknown atom")),
1021 }
1022 Ok(())
1023 }
1024
1025 /// Writes bytes in the given format.
1026 fn write_bytes(&mut self, bytes: &[u8], format: BytesFormat) {
1027 match format.encode(bytes) {
1028 Some(encoded) => self.write_escaped_str(&encoded),
1029 None => {
1030 self.write_char('[');
1031 for (idx, &byte) in bytes.iter().enumerate() {
1032 if idx > 0 {
1033 self.write_char(',');
1034 }
1035 self.write_u64(byte.into());
1036 }
1037 self.write_char(']');
1038 }
1039 }
1040 }
1041
1042 /// Writes bytes as string, for instance as map key.
1043 ///
1044 /// Bytes that would be sequences are base64.
1045 fn write_bytes_str(&mut self, bytes: &[u8], fallback: Option<&BytesFormat>) {
1046 let format = fallback.copied().unwrap_or(self.bytes);
1047 let encoded = format
1048 .encode(bytes)
1049 .or_else(|| BytesFormat::BASE64.encode(bytes))
1050 .unwrap_or_default();
1051 self.write_escaped_str(&encoded);
1052 }
1053
1054 #[inline(always)]
1055 pub(crate) fn write_str(&mut self, s: &str) {
1056 self.out.push_str(s);
1057 }
1058
1059 #[inline(always)]
1060 pub(crate) fn write_char(&mut self, c: char) {
1061 debug_assert!(c.is_ascii());
1062 self.out.push(c as u8);
1063 }
1064
1065 /// Writes a map key including the separator and the colon.
1066 #[inline]
1067 fn write_key(&mut self, key: &str, first: bool) {
1068 if find_escape(key.as_bytes()) != key.len() {
1069 if !first {
1070 self.write_char(',');
1071 }
1072 self.write_escaped_str_slow(key);
1073 self.write_char(':');
1074 return;
1075 }
1076 self.out.reserve(key.len() + 4);
1077 // SAFETY: the capacity was reserved above
1078 unsafe {
1079 if !first {
1080 self.out.push_unchecked(b',');
1081 }
1082 self.out.push_unchecked(b'"');
1083 self.out.push_str_unchecked(key);
1084 self.out.push_unchecked(b'"');
1085 self.out.push_unchecked(b':');
1086 }
1087 }
1088
1089 /// Writes a float with the shortest text that reads back as the same
1090 /// value of its type (`f32` or `f64`).
1091 #[inline]
1092 fn write_float<F: Float>(&mut self, val: F) {
1093 if val.is_finite() {
1094 #[cfg(feature = "zmij")]
1095 {
1096 self.write_str(zmij::Buffer::new().format_finite(val))
1097 }
1098 #[cfg(not(feature = "zmij"))]
1099 {
1100 self.write_str(&deser_core::__format::format_finite(val))
1101 }
1102 } else {
1103 self.write_str("null")
1104 }
1105 }
1106
1107 /// Writes an extension value as map key.
1108 ///
1109 /// Extension values that JSON does not natively support are written in
1110 /// their fallback representation.
1111 #[cold]
1112 fn write_ext_key(&mut self, ext: &ExtValue) -> Result<(), Error> {
1113 if ext.is::<u128>() || ext.is::<i128>() {
1114 self.write_char('"');
1115 self.write_ext_value(ext)?;
1116 self.write_char('"');
1117 return Ok(());
1118 }
1119 match ext.fallback() {
1120 Atom::Str(val) | Atom::Lexical(val) => self.write_escaped_str(&val),
1121 Atom::Char(c) => self.write_escaped_str(c.encode_utf8(&mut [0u8; 4])),
1122 Atom::U64(val) => {
1123 self.write_char('"');
1124 self.write_u64(val);
1125 self.write_char('"');
1126 }
1127 Atom::I64(val) => {
1128 self.write_char('"');
1129 self.write_i64(val);
1130 self.write_char('"');
1131 }
1132 Atom::Bool(val) => self.write_str(if val { "\"true\"" } else { "\"false\"" }),
1133 _ => {
1134 return Err(Error::new(
1135 ErrorKind::UnsupportedType,
1136 "JSON does not support this value for map keys",
1137 ));
1138 }
1139 }
1140 Ok(())
1141 }
1142
1143 /// Writes an extension value.
1144 ///
1145 /// Extension values that JSON does not natively support are written in
1146 /// their fallback representation.
1147 #[cold]
1148 fn write_ext_value(&mut self, ext: &ExtValue) -> Result<(), Error> {
1149 // JSON numbers have arbitrary precision, so wide integers and
1150 // decimals can be written natively.
1151 if let Some(&val) = ext.downcast_ref::<u128>() {
1152 self.write_int(val);
1153 return Ok(());
1154 } else if let Some(&val) = ext.downcast_ref::<i128>() {
1155 self.write_int(val);
1156 return Ok(());
1157 } else if let Some(val) = ext.downcast_ref::<BigInt>() {
1158 self.write_str(&val.to_string());
1159 return Ok(());
1160 } else if let Some(val) = ext.downcast_ref::<Decimal>() {
1161 // decimals use the syntax of JSON numbers
1162 self.write_str(val.as_str());
1163 return Ok(());
1164 } else if let Some(val) = ext.downcast_value_ref::<Number>() {
1165 // numbers keep their text, so they roundtrip exactly
1166 self.write_str(val.as_str());
1167 return Ok(());
1168 }
1169 match ext.fallback() {
1170 Atom::Null => self.write_str("null"),
1171 Atom::Bool(val) => self.write_str(if val { "true" } else { "false" }),
1172 Atom::Str(val) | Atom::Lexical(val) => self.write_escaped_str(&val),
1173 Atom::Char(c) => self.write_escaped_str(c.encode_utf8(&mut [0u8; 4])),
1174 Atom::U64(val) => self.write_u64(val),
1175 Atom::I64(val) => self.write_i64(val),
1176 Atom::F64(val) => self.write_float(val),
1177 Atom::F32(val) => self.write_float(val),
1178 // like in TOML the fallbacks of extension values are never
1179 // sequences
1180 Atom::Bytes(val) => self.write_bytes_str(&val, val.fallback),
1181 _ => {
1182 return Err(Error::new(
1183 ErrorKind::UnsupportedType,
1184 "JSON does not support this value",
1185 ));
1186 }
1187 }
1188 Ok(())
1189 }
1190
1191 fn write_int<I: core::fmt::Display>(&mut self, val: I) {
1192 self.write_str(&val.to_string())
1193 }
1194
1195 #[inline]
1196 fn write_u64(&mut self, val: u64) {
1197 self.write_str(IntBuffer::new().format_u64(val))
1198 }
1199
1200 #[inline]
1201 fn write_i64(&mut self, val: i64) {
1202 self.write_str(IntBuffer::new().format_i64(val))
1203 }
1204
1205 #[inline]
1206 fn write_escaped_str(&mut self, value: &str) {
1207 if find_escape(value.as_bytes()) != value.len() {
1208 return self.write_escaped_str_slow(value);
1209 }
1210 self.out.reserve(value.len() + 2);
1211 // SAFETY: the capacity was reserved above
1212 unsafe {
1213 self.out.push_unchecked(b'"');
1214 self.out.push_str_unchecked(value);
1215 self.out.push_unchecked(b'"');
1216 }
1217 }
1218
1219 #[inline(never)]
1220 fn write_escaped_str_slow(&mut self, value: &str) {
1221 self.write_char('"');
1222
1223 let bytes = value.as_bytes();
1224 let mut start = 0;
1225
1226 loop {
1227 let next = skip_to_escape(bytes, start);
1228 if start < next {
1229 self.write_str(&value[start..next]);
1230 }
1231 if next == bytes.len() {
1232 break;
1233 }
1234
1235 let byte = bytes[next];
1236 match ESCAPE[byte as usize] {
1237 self::BB => self.write_str("\\b"),
1238 self::TT => self.write_str("\\t"),
1239 self::NN => self.write_str("\\n"),
1240 self::FF => self.write_str("\\f"),
1241 self::RR => self.write_str("\\r"),
1242 self::QU => self.write_str("\\\""),
1243 self::BS => self.write_str("\\\\"),
1244 self::U => {
1245 static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef";
1246 self.write_str("\\u00");
1247 self.write_char(HEX_DIGITS[(byte >> 4) as usize] as char);
1248 self.write_char(HEX_DIGITS[(byte & 0xF) as usize] as char);
1249 }
1250 _ => unreachable!(),
1251 }
1252
1253 start = next + 1;
1254 }
1255
1256 self.write_char('"');
1257 }
1258}
1259
1260const BB: u8 = b'b'; // \x08
1261const TT: u8 = b't'; // \x09
1262const NN: u8 = b'n'; // \x0A
1263const FF: u8 = b'f'; // \x0C
1264const RR: u8 = b'r'; // \x0D
1265const QU: u8 = b'"'; // \x22
1266const BS: u8 = b'\\'; // \x5C
1267const U: u8 = b'u'; // \x00...\x1F except the ones above
1268
1269// Lookup table of escape sequences. A value of b'x' at index i means that byte
1270// i is escaped as "\x" in JSON. A value of 0 means that byte i is not escaped.
1271#[rustfmt::skip]
1272static ESCAPE: [u8; 256] = [
1273 // 1 2 3 4 5 6 7 8 9 A B C D E F
1274 U, U, U, U, U, U, U, U, BB, TT, NN, U, FF, RR, U, U, // 0
1275 U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, // 1
1276 0, 0, QU, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2
1277 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3
1278 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4
1279 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, BS, 0, 0, 0, // 5
1280 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
1281 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
1282 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
1283 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
1284 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A
1285 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B
1286 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C
1287 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D
1288 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E
1289 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F
1290];
1291
1292/// The floats that are written (`f32` and `f64`).
1293#[cfg(feature = "zmij")]
1294trait Float: zmij::Float + deser_core::__format::Float {}
1295
1296#[cfg(feature = "zmij")]
1297impl<F: zmij::Float + deser_core::__format::Float> Float for F {}
1298
1299/// The floats that are written (`f32` and `f64`).
1300#[cfg(not(feature = "zmij"))]
1301trait Float: deser_core::__format::Float {}
1302
1303#[cfg(not(feature = "zmij"))]
1304impl<F: deser_core::__format::Float> Float for F {}
1305
1306/// Serializes a value to JSON.
1307///
1308/// This uses the default [`SerializerConfig`].
1309#[inline]
1310pub fn to_string(value: &dyn Serialize) -> Result<String, Error> {
1311 SerializerConfig::new().to_string(value)
1312}
1313
1314/// Returns the text of an implicit value if it's a JSON literal for the
1315/// same value.
1316///
1317/// This keeps the text of numbers like `1.10` which would otherwise be
1318/// written as `1.1`. Text that is not JSON (like `0x1F` or `~`) is not.
1319fn json_literal<'a>(value: &'a Implicit) -> Option<&'a str> {
1320 let text = value.text().as_str();
1321 let same = match value.value() {
1322 ImplicitValue::Null => text == "null",
1323 ImplicitValue::Bool(value) => text == if value { "true" } else { "false" },
1324 ImplicitValue::U64(value) => is_json_int(text) && text.parse::<u64>() == Ok(value),
1325 ImplicitValue::I64(value) => is_json_int(text) && text.parse::<i64>() == Ok(value),
1326 ImplicitValue::F64(value) => {
1327 value.is_finite()
1328 && Number::parse(text)
1329 .is_ok_and(|x| !x.is_integer() && x.value().to_bits() == value.to_bits())
1330 }
1331 _ => false,
1332 };
1333 same.then_some(text)
1334}
1335
1336/// Checks the syntax of JSON integers (an optional minus and digits
1337/// without leading zeros).
1338fn is_json_int(text: &str) -> bool {
1339 let digits = text.strip_prefix('-').unwrap_or(text).as_bytes();
1340 match digits {
1341 [b'0'] => true,
1342 [b'1'..=b'9', rest @ ..] => rest.iter().all(u8::is_ascii_digit),
1343 _ => false,
1344 }
1345}