Skip to main content

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}