Skip to main content

deser_jsonc/
ser.rs

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