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