Skip to main content

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