Skip to main content

nextjson/
ser.rs

1//! Serialization: buffered [`Encoder`], the [`NsonSerialize`] trait, and
2//! standard-library implementations.
3//!
4//! Design points:
5//! - hand-written stack-buffer integer and float output;
6//! - single-pass string escaping with bulk copy for unescaped input;
7//! - per-container first-element flag stack for zero-cost separators.
8
9use alloc::borrow::Cow;
10use alloc::boxed::Box;
11use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
12use alloc::rc::Rc;
13use alloc::string::{String, ToString};
14use alloc::sync::Arc;
15use alloc::vec::Vec;
16use core::cell::{Cell, RefCell};
17use core::fmt::{self, Write as _};
18use core::marker::PhantomData;
19use core::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
20use core::time::Duration;
21
22use crate::error::{Error, ErrorKind, FormatError, Result};
23use crate::event_state::{EventState, Kind};
24use crate::map::Map;
25use crate::number::Number;
26use crate::schema::{NsonSchema, TypeSchema};
27use crate::value::Value;
28use crate::write::Write;
29
30/// Serialization configuration.
31#[derive(Clone, Debug)]
32pub struct EncodeConfig {
33    /// Pretty-print output (indentation + newlines). Default `false`.
34    pub pretty: bool,
35    /// Indentation string used by pretty printing. Default two spaces.
36    pub indent: &'static str,
37    /// Escape all non-ASCII characters as `\uXXXX`. Default `false`.
38    pub escape_non_ascii: bool,
39}
40
41impl Default for EncodeConfig {
42    fn default() -> Self {
43        EncodeConfig {
44            pretty: false,
45            indent: "  ",
46            escape_non_ascii: false,
47        }
48    }
49}
50
51impl EncodeConfig {
52    /// Compact output config (default).
53    pub fn compact() -> Self {
54        EncodeConfig::default()
55    }
56    /// Pretty-printed output config.
57    pub fn pretty() -> Self {
58        EncodeConfig {
59            pretty: true,
60            ..EncodeConfig::default()
61        }
62    }
63    /// Set the indentation string.
64    pub fn indent(mut self, indent: &'static str) -> Self {
65        self.indent = indent;
66        self
67    }
68    /// Set whether to escape non-ASCII.
69    pub fn escape_non_ascii(mut self, on: bool) -> Self {
70        self.escape_non_ascii = on;
71        self
72    }
73}
74
75/// Format-neutral emission contract implemented by every destination codec.
76///
77/// `NsonSerialize::nextencode` is generic over this trait, so one type
78/// implementation can target every codec whose data model represents the
79/// emitted values. Binary codecs can use [`separator`] and [`key`] as counting
80/// signals and patch length prefixes when a container closes. Some
81/// document-oriented codecs collect the event stream before emission.
82///
83/// [`separator`]: FormatEncoder::separator
84/// [`key`]: FormatEncoder::key
85pub trait FormatEncoder {
86    /// The error type produced by this format's methods.
87    ///
88    /// External codecs may use their own error type; it only needs to wrap
89    /// [`crate::error::Error`] so generic serialization code can propagate
90    /// format failures. The built-in formats all use
91    /// [`crate::error::Error`].
92    type Error: FormatError;
93
94    /// Begin an array container.
95    fn begin_array(&mut self) -> Result<(), Self::Error>;
96    /// Emit the separator preceding a subsequent array element.
97    ///
98    /// Called once per element, including the first, so binary codecs can use
99    /// it as an element counter.
100    fn separator(&mut self) -> Result<(), Self::Error>;
101    /// End the current array container.
102    fn end_array(&mut self) -> Result<(), Self::Error>;
103    /// Begin an object container.
104    fn begin_object(&mut self) -> Result<(), Self::Error>;
105    /// Emit an object key.
106    ///
107    /// Called once per entry, including the first, so binary codecs can use it
108    /// as an entry counter.
109    fn key(&mut self, key: &str) -> Result<(), Self::Error>;
110    /// End the current object container.
111    fn end_object(&mut self) -> Result<(), Self::Error>;
112    /// Emit `null`.
113    fn write_null(&mut self) -> Result<(), Self::Error>;
114    /// Emit a boolean.
115    fn write_bool(&mut self, value: bool) -> Result<(), Self::Error>;
116    /// Emit a UTF-8 string.
117    fn write_str(&mut self, value: &str) -> Result<(), Self::Error>;
118    /// Emit a single character (a one-scalar string).
119    fn write_char(&mut self, value: char) -> Result<(), Self::Error>;
120    /// Emit a number preserving its exact internal kind.
121    fn write_number(&mut self, value: &Number) -> Result<(), Self::Error>;
122    /// Emit an `i64`.
123    fn write_i64(&mut self, value: i64) -> Result<(), Self::Error>;
124    /// Emit a `u64`.
125    fn write_u64(&mut self, value: u64) -> Result<(), Self::Error>;
126    /// Emit an `i128`.
127    fn write_i128(&mut self, value: i128) -> Result<(), Self::Error>;
128    /// Emit a `u128`.
129    fn write_u128(&mut self, value: u128) -> Result<(), Self::Error>;
130    /// Emit an `f64` (shortest round-trip).
131    fn write_f64(&mut self, value: f64) -> Result<(), Self::Error>;
132    /// Emit an `f32` (shortest round-trip).
133    fn write_f32(&mut self, value: f32) -> Result<(), Self::Error>;
134
135    /// Emit an `i8` (default: widen to [`write_i64`](FormatEncoder::write_i64)).
136    ///
137    /// Binary codecs that preserve source width on the wire override this.
138    fn write_i8(&mut self, value: i8) -> Result<(), Self::Error> {
139        self.write_i64(value as i64)
140    }
141    /// Emit an `i16` (default: widen to [`write_i64`](FormatEncoder::write_i64)).
142    fn write_i16(&mut self, value: i16) -> Result<(), Self::Error> {
143        self.write_i64(value as i64)
144    }
145    /// Emit an `i32` (default: widen to [`write_i64`](FormatEncoder::write_i64)).
146    fn write_i32(&mut self, value: i32) -> Result<(), Self::Error> {
147        self.write_i64(value as i64)
148    }
149    /// Emit a `u8` (default: widen to [`write_u64`](FormatEncoder::write_u64)).
150    fn write_u8(&mut self, value: u8) -> Result<(), Self::Error> {
151        self.write_u64(value as u64)
152    }
153    /// Emit a `u16` (default: widen to [`write_u64`](FormatEncoder::write_u64)).
154    fn write_u16(&mut self, value: u16) -> Result<(), Self::Error> {
155        self.write_u64(value as u64)
156    }
157    /// Emit a `u32` (default: widen to [`write_u64`](FormatEncoder::write_u64)).
158    fn write_u32(&mut self, value: u32) -> Result<(), Self::Error> {
159        self.write_u64(value as u64)
160    }
161
162    /// Emit a byte sequence.
163    ///
164    /// The default emits a sequence of `u8` values, which is lossless in every
165    /// self-describing format (JSON text becomes `[1, 2, 3]`, matching
166    /// serde_json). Binary codecs override this to emit a native byte-string
167    /// wire type (length prefix + raw bytes), which is far more compact.
168    fn write_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> {
169        self.begin_array()?;
170        for &byte in value {
171            self.separator()?;
172            self.write_u8(byte)?;
173        }
174        self.end_array()
175    }
176
177    /// Emit `Option::None`.
178    ///
179    /// The default maps to [`write_null`](FormatEncoder::write_null), which is
180    /// exactly the JSON shape. Binary codecs override this to emit a
181    /// distinguishing tag so `None` stays distinct from a `Some` payload.
182    fn write_none(&mut self) -> Result<(), Self::Error> {
183        self.write_null()
184    }
185    /// Emit the marker that the following value is `Option::Some`.
186    ///
187    /// The default emits nothing (the payload follows immediately), which is
188    /// the JSON shape. Binary codecs override this to emit a distinguishing
189    /// tag.
190    fn write_some(&mut self) -> Result<(), Self::Error> {
191        Ok(())
192    }
193
194    /// Emit a map key.
195    ///
196    /// The default serializes the key to a string and emits it with
197    /// [`key`](FormatEncoder::key) (the JSON shape). Binary codecs override
198    /// this to write the key as a plain value, which supports non-string keys
199    /// such as `BTreeMap<u8, V>` without string round-tripping.
200    fn map_key<K: NsonSerialize>(&mut self, key: &K) -> Result<(), Self::Error> {
201        let string = key_to_str(key)?;
202        self.key(&string)
203    }
204
205    /// Whether this format produces human-readable output.
206    ///
207    /// Text formats return `true`; binary codecs return `false`. Types that
208    /// encode differently for humans (timestamps, identifiers, byte strings)
209    /// branch on this, mirroring serde's `Serializer::is_human_readable`.
210    fn is_human_readable(&self) -> bool {
211        true
212    }
213}
214
215/// The protocol state itself lives in
216/// The protocol state itself lives in `event_state::EventState` so it is
217/// shared with the cross-format sinks; this wrapper only maps
218/// `FormatEncoder` calls onto it and forwards them to the inner codec.
219pub struct CheckedEncoder<'a, E: FormatEncoder + ?Sized> {
220    inner: &'a mut E,
221    state: EventState,
222}
223
224impl<'a, E: FormatEncoder + ?Sized> CheckedEncoder<'a, E> {
225    pub(crate) fn new(inner: &'a mut E) -> Self {
226        CheckedEncoder {
227            inner,
228            // Format encoders emit explicit separators between array
229            // elements, so arrays must alternate separator / value.
230            state: EventState::new(true),
231        }
232    }
233
234    fn value(&mut self) -> Result<(), E::Error> {
235        self.state.value().map(drop).map_err(Into::into)
236    }
237
238    pub fn finish(self) -> Result<(), E::Error> {
239        self.state.finish().map_err(Into::into)
240    }
241}
242
243impl<E: FormatEncoder + ?Sized> FormatEncoder for CheckedEncoder<'_, E> {
244    type Error = E::Error;
245
246    fn begin_array(&mut self) -> Result<(), E::Error> {
247        self.state.begin(Kind::Array).map(drop)?;
248        self.inner.begin_array()
249    }
250
251    fn separator(&mut self) -> Result<(), E::Error> {
252        self.state.separator()?;
253        self.inner.separator()
254    }
255
256    fn end_array(&mut self) -> Result<(), E::Error> {
257        self.state.end(Kind::Array)?;
258        self.inner.end_array()
259    }
260
261    fn begin_object(&mut self) -> Result<(), E::Error> {
262        self.state.begin(Kind::Object).map(drop)?;
263        self.inner.begin_object()
264    }
265
266    fn key(&mut self, key: &str) -> Result<(), E::Error> {
267        self.state.key()?;
268        self.inner.key(key)
269    }
270
271    fn end_object(&mut self) -> Result<(), E::Error> {
272        self.state.end(Kind::Object)?;
273        self.inner.end_object()
274    }
275
276    fn write_null(&mut self) -> Result<(), E::Error> {
277        self.value()?;
278        self.inner.write_null()
279    }
280
281    fn write_bool(&mut self, value: bool) -> Result<(), E::Error> {
282        self.value()?;
283        self.inner.write_bool(value)
284    }
285
286    fn write_str(&mut self, value: &str) -> Result<(), E::Error> {
287        self.value()?;
288        self.inner.write_str(value)
289    }
290
291    fn write_char(&mut self, value: char) -> Result<(), E::Error> {
292        self.value()?;
293        self.inner.write_char(value)
294    }
295
296    fn write_number(&mut self, value: &Number) -> Result<(), E::Error> {
297        self.value()?;
298        self.inner.write_number(value)
299    }
300
301    fn write_i64(&mut self, value: i64) -> Result<(), E::Error> {
302        self.value()?;
303        self.inner.write_i64(value)
304    }
305
306    fn write_u64(&mut self, value: u64) -> Result<(), E::Error> {
307        self.value()?;
308        self.inner.write_u64(value)
309    }
310
311    fn write_i128(&mut self, value: i128) -> Result<(), E::Error> {
312        self.value()?;
313        self.inner.write_i128(value)
314    }
315
316    fn write_u128(&mut self, value: u128) -> Result<(), E::Error> {
317        self.value()?;
318        self.inner.write_u128(value)
319    }
320
321    fn write_f64(&mut self, value: f64) -> Result<(), E::Error> {
322        self.value()?;
323        self.inner.write_f64(value)
324    }
325
326    fn write_f32(&mut self, value: f32) -> Result<(), E::Error> {
327        self.value()?;
328        self.inner.write_f32(value)
329    }
330
331    fn write_i8(&mut self, value: i8) -> Result<(), E::Error> {
332        self.value()?;
333        self.inner.write_i8(value)
334    }
335
336    fn write_i16(&mut self, value: i16) -> Result<(), E::Error> {
337        self.value()?;
338        self.inner.write_i16(value)
339    }
340
341    fn write_i32(&mut self, value: i32) -> Result<(), E::Error> {
342        self.value()?;
343        self.inner.write_i32(value)
344    }
345
346    fn write_u8(&mut self, value: u8) -> Result<(), E::Error> {
347        self.value()?;
348        self.inner.write_u8(value)
349    }
350
351    fn write_u16(&mut self, value: u16) -> Result<(), E::Error> {
352        self.value()?;
353        self.inner.write_u16(value)
354    }
355
356    fn write_u32(&mut self, value: u32) -> Result<(), E::Error> {
357        self.value()?;
358        self.inner.write_u32(value)
359    }
360
361    fn write_bytes(&mut self, value: &[u8]) -> Result<(), E::Error> {
362        self.value()?;
363        self.inner.write_bytes(value)
364    }
365
366    fn write_none(&mut self) -> Result<(), E::Error> {
367        self.value()?;
368        self.inner.write_none()
369    }
370
371    fn write_some(&mut self) -> Result<(), E::Error> {
372        // A `Some` payload is not itself a value: the following value consumes
373        // the value slot, so no protocol transition happens here.
374        self.inner.write_some()
375    }
376
377    fn map_key<K: NsonSerialize>(&mut self, key: &K) -> Result<(), E::Error> {
378        self.state.key()?;
379        self.inner.map_key(key)
380    }
381
382    fn is_human_readable(&self) -> bool {
383        self.inner.is_human_readable()
384    }
385}
386
387impl<W: Write, const VALIDATE: bool> FormatEncoder for Encoder<W, VALIDATE> {
388    type Error = crate::error::Error;
389
390    fn begin_array(&mut self) -> Result<(), Self::Error> {
391        Encoder::begin_array(self)
392    }
393    fn separator(&mut self) -> Result<(), Self::Error> {
394        Encoder::separator(self)
395    }
396    fn end_array(&mut self) -> Result<(), Self::Error> {
397        Encoder::end_array(self)
398    }
399    fn begin_object(&mut self) -> Result<(), Self::Error> {
400        Encoder::begin_object(self)
401    }
402    fn key(&mut self, key: &str) -> Result<(), Self::Error> {
403        Encoder::key(self, key)
404    }
405    fn end_object(&mut self) -> Result<(), Self::Error> {
406        Encoder::end_object(self)
407    }
408    fn write_null(&mut self) -> Result<(), Self::Error> {
409        Encoder::write_null(self)
410    }
411    fn write_bool(&mut self, value: bool) -> Result<(), Self::Error> {
412        Encoder::write_bool(self, value)
413    }
414    fn write_str(&mut self, value: &str) -> Result<(), Self::Error> {
415        Encoder::write_str(self, value)
416    }
417    fn write_char(&mut self, value: char) -> Result<(), Self::Error> {
418        Encoder::write_char(self, value)
419    }
420    fn write_number(&mut self, value: &Number) -> Result<(), Self::Error> {
421        Encoder::write_number(self, value)
422    }
423    fn write_i64(&mut self, value: i64) -> Result<(), Self::Error> {
424        Encoder::write_i64(self, value)
425    }
426    fn write_u64(&mut self, value: u64) -> Result<(), Self::Error> {
427        Encoder::write_u64(self, value)
428    }
429    fn write_i128(&mut self, value: i128) -> Result<(), Self::Error> {
430        Encoder::write_i128(self, value)
431    }
432    fn write_u128(&mut self, value: u128) -> Result<(), Self::Error> {
433        Encoder::write_u128(self, value)
434    }
435    fn write_f64(&mut self, value: f64) -> Result<(), Self::Error> {
436        Encoder::write_f64(self, value)
437    }
438    fn write_f32(&mut self, value: f32) -> Result<(), Self::Error> {
439        Encoder::write_f32(self, value)
440    }
441    fn write_i8(&mut self, value: i8) -> Result<(), Self::Error> {
442        Encoder::write_i64(self, value as i64)
443    }
444    fn write_i16(&mut self, value: i16) -> Result<(), Self::Error> {
445        Encoder::write_i64(self, value as i64)
446    }
447    fn write_i32(&mut self, value: i32) -> Result<(), Self::Error> {
448        Encoder::write_i64(self, value as i64)
449    }
450    fn write_u8(&mut self, value: u8) -> Result<(), Self::Error> {
451        Encoder::write_u64(self, value as u64)
452    }
453    fn write_u16(&mut self, value: u16) -> Result<(), Self::Error> {
454        Encoder::write_u64(self, value as u64)
455    }
456    fn write_u32(&mut self, value: u32) -> Result<(), Self::Error> {
457        Encoder::write_u64(self, value as u64)
458    }
459    fn write_none(&mut self) -> Result<(), Self::Error> {
460        Encoder::write_null(self)
461    }
462}
463
464/// Serialization trait: nextencode `Self` into any [`FormatEncoder`].
465///
466/// The format is a generic parameter, so method bodies are monomorphized at
467/// compile time with no dynamic dispatch. JSON, CBOR, and every codec in
468/// [`crate::formats`] implement [`FormatEncoder`].
469pub trait NsonSerialize: NsonSchema {
470    /// Next-encode `self` into `encoder`.
471    ///
472    /// Errors are produced in the target format's own error type
473    /// ([`FormatEncoder::Error`]).
474    fn nextencode<E: FormatEncoder>(&self, encoder: &mut E) -> Result<(), E::Error>;
475}
476
477/// Trusted JSON encoder variant: skips per-value event-protocol validation.
478///
479/// Use this when the caller provably follows the serialization protocol —
480/// the repository-owned derive macros do — in exchange for ~2x encoding
481/// throughput. Misuse (a hand-written implementation emitting values out of
482/// order) silently produces malformed JSON instead of an error, so this is
483/// the wrong type for unverified callers. See [`Encoder`].
484pub type FastEncoder<W> = Encoder<W, false>;
485
486/// JSON encoder with internal buffering and indentation state.
487///
488/// All bytes are buffered in an internal `Vec<u8>` and flushed to `W` once a
489/// threshold is crossed, keeping memory bounded.
490///
491/// The `VALIDATE` const parameter selects the event-protocol policy:
492///
493/// - `Encoder<W>` (the default, `VALIDATE = true`) checks every call against
494///   the serialization event protocol and reports misuse as an error. This
495///   is the safe surface for hand-written `NsonSerialize` implementations.
496/// - `Encoder<W, false>` trusts the caller to follow the protocol (the
497///   repository-owned derive macros are verified to do so) and skips every
498///   per-value check. The top-level `nextencode` / `to_vec` / `to_string`
499///   entry points use this fast path.
500///
501/// Both emit byte-identical output for protocol-conforming callers; the
502/// fast path trades misuse diagnostics for ~2x encoding throughput.
503pub struct Encoder<W: Write, const VALIDATE: bool = true> {
504    writer: W,
505    buf: Vec<u8>,
506    depth: usize,
507    frames: Vec<EncodeFrame>,
508    root_written: bool,
509    pretty: bool,
510    indent: &'static str,
511    escape_non_ascii: bool,
512    flush_threshold: usize,
513}
514
515enum EncodeFrame {
516    Array { first: bool, ready: bool },
517    Object { first: bool, pending_value: bool },
518}
519
520const FLUSH_THRESHOLD: usize = 8192;
521
522impl<W: Write, const VALIDATE: bool> Encoder<W, VALIDATE> {
523    /// Create an encoder with the default (compact) config.
524    pub fn new(writer: W) -> Self {
525        Encoder::with_config(writer, EncodeConfig::default())
526    }
527
528    /// Create an encoder with the given config.
529    pub fn with_config(writer: W, config: EncodeConfig) -> Self {
530        Encoder {
531            writer,
532            buf: Vec::with_capacity(1024),
533            depth: 0,
534            // Preallocate for the common nesting depth so deeply nested
535            // containers do not reallocate on every `begin_*` push.
536            frames: Vec::with_capacity(32),
537            root_written: false,
538            pretty: config.pretty,
539            indent: config.indent,
540            escape_non_ascii: config.escape_non_ascii,
541            flush_threshold: FLUSH_THRESHOLD,
542        }
543    }
544
545    /// Flush the internal buffer and return the underlying writer.
546    pub fn finish(mut self) -> Result<W> {
547        if VALIDATE {
548            self.validate_finished()?;
549        }
550        self.writer.write_all(&self.buf)?;
551        self.buf.clear();
552        self.writer.flush()?;
553        Ok(self.writer)
554    }
555
556    /// Flush the internal buffer without consuming self.
557    pub fn flush(&mut self) -> Result<()> {
558        self.writer.write_all(&self.buf)?;
559        self.buf.clear();
560        self.writer.flush()
561    }
562
563    #[inline]
564    fn maybe_flush(&mut self) -> Result<()> {
565        if self.buf.len() >= self.flush_threshold {
566            self.writer.write_all(&self.buf)?;
567            self.buf.clear();
568        }
569        Ok(())
570    }
571
572    // -----------------------------------------------------------------
573    // container primitives
574    // -----------------------------------------------------------------
575
576    /// Open an object: write `{`.
577    pub fn begin_object(&mut self) -> Result<()> {
578        if VALIDATE {
579            self.start_value()?;
580        }
581        self.buf.push(b'{');
582        self.frames.push(EncodeFrame::Object {
583            first: true,
584            pending_value: false,
585        });
586        self.depth += 1;
587        if self.pretty {
588            self.buf.push(b'\n');
589            self.write_indent();
590        }
591        self.maybe_flush()
592    }
593
594    /// Close an object: write `}`.
595    pub fn end_object(&mut self) -> Result<()> {
596        if VALIDATE {
597            match self.frames.last() {
598                Some(EncodeFrame::Object {
599                    pending_value: false,
600                    ..
601                }) => {}
602                Some(EncodeFrame::Object {
603                    pending_value: true,
604                    ..
605                }) => return Err(Error::custom("object ended before keyed value")),
606                Some(EncodeFrame::Array { .. }) => {
607                    return Err(Error::custom("mismatched object end inside array"));
608                }
609                None => return Err(Error::custom("object end without matching start")),
610            }
611        }
612        self.frames.pop();
613        self.depth -= 1;
614        if self.pretty {
615            self.buf.push(b'\n');
616            self.write_indent();
617        }
618        self.buf.push(b'}');
619        self.maybe_flush()
620    }
621
622    /// Open an array: write `[`.
623    pub fn begin_array(&mut self) -> Result<()> {
624        if VALIDATE {
625            self.start_value()?;
626        }
627        self.buf.push(b'[');
628        self.frames.push(EncodeFrame::Array {
629            first: true,
630            ready: false,
631        });
632        self.depth += 1;
633        if self.pretty {
634            self.buf.push(b'\n');
635            self.write_indent();
636        }
637        self.maybe_flush()
638    }
639
640    /// Close an array: write `]`.
641    pub fn end_array(&mut self) -> Result<()> {
642        if VALIDATE {
643            match self.frames.last() {
644                Some(EncodeFrame::Array { ready: false, .. }) => {}
645                Some(EncodeFrame::Array { ready: true, .. }) => {
646                    return Err(Error::custom("array ended after separator without value"));
647                }
648                Some(EncodeFrame::Object { .. }) => {
649                    return Err(Error::custom("mismatched array end inside object"));
650                }
651                None => return Err(Error::custom("array end without matching start")),
652            }
653        }
654        self.frames.pop();
655        self.depth -= 1;
656        if self.pretty {
657            self.buf.push(b'\n');
658            self.write_indent();
659        }
660        self.buf.push(b']');
661        self.maybe_flush()
662    }
663
664    /// Write an object key: separator + `"key":`.
665    pub fn key(&mut self, key: &str) -> Result<()> {
666        let first = if VALIDATE {
667            match self.frames.last_mut() {
668                Some(EncodeFrame::Object {
669                    first,
670                    pending_value,
671                }) if !*pending_value => {
672                    *pending_value = true;
673                    core::mem::replace(first, false)
674                }
675                Some(EncodeFrame::Object { .. }) => {
676                    return Err(Error::custom("object value required after key"));
677                }
678                _ => return Err(Error::custom("object key outside object")),
679            }
680        } else {
681            match self.frames.last_mut() {
682                Some(EncodeFrame::Object { first, .. }) => core::mem::replace(first, false),
683                _ => return Err(Error::custom("fast encoder: object key outside object")),
684            }
685        };
686        self.write_separator(first);
687        write_escaped_str(&mut self.buf, key, self.escape_non_ascii);
688        self.buf.push(b':');
689        if self.pretty {
690            self.buf.push(b' ');
691        }
692        Ok(())
693    }
694
695    /// Write an element / key separator.
696    ///
697    /// The first entry of a container produces nothing; subsequent entries
698    /// produce `,` (plus newline and indent in pretty mode).
699    pub fn separator(&mut self) -> Result<()> {
700        let first = if VALIDATE {
701            match self.frames.last_mut() {
702                Some(EncodeFrame::Array { first, ready }) if !*ready => {
703                    *ready = true;
704                    core::mem::replace(first, false)
705                }
706                Some(EncodeFrame::Array { .. }) => {
707                    return Err(Error::custom("array value required after separator"));
708                }
709                _ => return Err(Error::custom("array separator outside array")),
710            }
711        } else {
712            match self.frames.last_mut() {
713                Some(EncodeFrame::Array { first, .. }) => core::mem::replace(first, false),
714                _ => return Err(Error::custom("fast encoder: array separator outside array")),
715            }
716        };
717        self.write_separator(first);
718        Ok(())
719    }
720
721    fn write_separator(&mut self, first: bool) {
722        if !first {
723            self.buf.push(b',');
724            if self.pretty {
725                self.buf.push(b'\n');
726                self.write_indent();
727            }
728        }
729    }
730
731    /// Validate that a value may be written now (validating policy only).
732    #[inline]
733    fn start_value(&mut self) -> Result<()> {
734        match self.frames.last_mut() {
735            Some(EncodeFrame::Array { ready, .. }) if *ready => {
736                *ready = false;
737                Ok(())
738            }
739            Some(EncodeFrame::Array { .. }) => {
740                Err(Error::custom("array separator required before value"))
741            }
742            Some(EncodeFrame::Object { pending_value, .. }) if *pending_value => {
743                *pending_value = false;
744                Ok(())
745            }
746            Some(EncodeFrame::Object { .. }) => {
747                Err(Error::custom("object key required before value"))
748            }
749            None if self.root_written => Err(Error::custom("multiple root values")),
750            None => {
751                self.root_written = true;
752                Ok(())
753            }
754        }
755    }
756
757    fn validate_finished(&self) -> Result<()> {
758        if !self.root_written {
759            return Err(Error::custom("encoder did not receive a root value"));
760        }
761        if !self.frames.is_empty() {
762            return Err(Error::custom("encoder finished inside a container"));
763        }
764        Ok(())
765    }
766
767    #[inline]
768    fn write_indent(&mut self) {
769        for _ in 0..self.depth {
770            self.buf.extend_from_slice(self.indent.as_bytes());
771        }
772    }
773
774    // -----------------------------------------------------------------
775    // scalar primitives
776    // -----------------------------------------------------------------
777
778    /// Write `null`.
779    pub fn write_null(&mut self) -> Result<()> {
780        if VALIDATE {
781            self.start_value()?;
782        }
783        self.buf.extend_from_slice(b"null");
784        self.maybe_flush()
785    }
786
787    /// Write a boolean.
788    pub fn write_bool(&mut self, v: bool) -> Result<()> {
789        if VALIDATE {
790            self.start_value()?;
791        }
792        self.buf
793            .extend_from_slice(if v { b"true" } else { b"false" });
794        self.maybe_flush()
795    }
796
797    /// Write a string (auto-escaped).
798    pub fn write_str(&mut self, s: &str) -> Result<()> {
799        if VALIDATE {
800            self.start_value()?;
801        }
802        write_escaped_str(&mut self.buf, s, self.escape_non_ascii);
803        self.maybe_flush()
804    }
805
806    /// Write a character (a one-scalar string) on the hot path.
807    ///
808    /// Implemented directly instead of routing through
809    /// [`Encoder::write_str`](Encoder::write_str) so a single character skips
810    /// the full-string raw-copy scan.
811    pub fn write_char(&mut self, c: char) -> Result<()> {
812        if VALIDATE {
813            self.start_value()?;
814        }
815        self.buf.push(b'"');
816        match c {
817            '"' => self.buf.extend_from_slice(b"\\\""),
818            '\\' => self.buf.extend_from_slice(b"\\\\"),
819            '\n' => self.buf.extend_from_slice(b"\\n"),
820            '\r' => self.buf.extend_from_slice(b"\\r"),
821            '\t' => self.buf.extend_from_slice(b"\\t"),
822            '\u{8}' => self.buf.extend_from_slice(b"\\b"),
823            '\u{c}' => self.buf.extend_from_slice(b"\\f"),
824            c if (c as u32) < 0x20 => {
825                self.buf.extend_from_slice(b"\\u00");
826                const HEX: &[u8; 16] = b"0123456789abcdef";
827                let v = c as u32;
828                self.buf.push(HEX[(v >> 4) as usize]);
829                self.buf.push(HEX[(v & 0xF) as usize]);
830            }
831            _ if self.escape_non_ascii && (c as u32) >= 0x80 => {
832                write_unicode_escape(&mut self.buf, c);
833            }
834            _ => {
835                let mut tmp = [0u8; 4];
836                self.buf
837                    .extend_from_slice(c.encode_utf8(&mut tmp).as_bytes());
838            }
839        }
840        self.buf.push(b'"');
841        self.maybe_flush()
842    }
843
844    /// Write a number.
845    pub fn write_number(&mut self, n: &Number) -> Result<()> {
846        match *n {
847            Number::I64(v) => self.write_i64(v),
848            Number::U64(v) => self.write_u64(v),
849            Number::I128(v) => self.write_i128(v),
850            Number::U128(v) => self.write_u128(v),
851            Number::F64(v) => self.write_f64(v),
852        }
853    }
854
855    /// Write an `i64`.
856    pub fn write_i64(&mut self, v: i64) -> Result<()> {
857        if VALIDATE {
858            self.start_value()?;
859        }
860        write_i64_into(&mut self.buf, v);
861        self.maybe_flush()
862    }
863
864    /// Write a `u64`.
865    pub fn write_u64(&mut self, v: u64) -> Result<()> {
866        if VALIDATE {
867            self.start_value()?;
868        }
869        write_u64_into(&mut self.buf, v);
870        self.maybe_flush()
871    }
872
873    /// Write an `i128`.
874    pub fn write_i128(&mut self, v: i128) -> Result<()> {
875        if VALIDATE {
876            self.start_value()?;
877        }
878        write_signed_integer_into(&mut self.buf, v);
879        self.maybe_flush()
880    }
881
882    /// Write a `u128`.
883    pub fn write_u128(&mut self, v: u128) -> Result<()> {
884        if VALIDATE {
885            self.start_value()?;
886        }
887        write_unsigned_integer_into(&mut self.buf, v);
888        self.maybe_flush()
889    }
890
891    /// Write an `f64` (shortest round-trip; non-finite values error).
892    ///
893    /// Integral floats are written as `1.0` rather than `1` so float-ness
894    /// survives round-trips.
895    pub fn write_f64(&mut self, v: f64) -> Result<()> {
896        if !v.is_finite() {
897            return Err(Error::new(ErrorKind::NonFiniteFloat, None, None, 0));
898        }
899        if VALIDATE {
900            self.start_value()?;
901        }
902        write_float_into(&mut self.buf, v)?;
903        self.maybe_flush()
904    }
905
906    /// Write an `f32` using its shortest round-trip representation.
907    pub fn write_f32(&mut self, v: f32) -> Result<()> {
908        if !v.is_finite() {
909            return Err(Error::new(ErrorKind::NonFiniteFloat, None, None, 0));
910        }
911        if VALIDATE {
912            self.start_value()?;
913        }
914        write_float_into(&mut self.buf, v)?;
915        self.maybe_flush()
916    }
917}
918
919impl<const VALIDATE: bool> Encoder<Vec<u8>, VALIDATE> {
920    pub(crate) fn for_vec(config: EncodeConfig) -> Self {
921        let mut encoder = Encoder::with_config(Vec::new(), config);
922        encoder.flush_threshold = usize::MAX;
923        encoder
924    }
925
926    pub(crate) fn finish_vec(mut self) -> Result<Vec<u8>> {
927        if VALIDATE {
928            self.validate_finished()?;
929        }
930        debug_assert!(self.writer.is_empty());
931        Ok(core::mem::take(&mut self.buf))
932    }
933}
934
935/// Whether a 64-bit chunk contains any byte that must be escaped in JSON.
936///
937/// SWAR (SIMD-within-a-register) detection, no `unsafe`: control characters
938/// (< 0x20), `"`, `\`, and (when `escape_non_ascii`) any byte >= 0x80. The
939/// `hasless` trick answers "does any byte satisfy the predicate" correctly
940/// even when borrow propagation blurs which byte, because a borrow only
941/// happens when a lower byte is itself a true positive.
942#[inline]
943fn chunk_needs_escape(chunk: u64, escape_non_ascii: bool) -> bool {
944    const HIGH: u64 = 0x8080_8080_8080_8080;
945    const ONES: u64 = 0x0101_0101_0101_0101;
946    // Any byte < 0x20.
947    if (chunk.wrapping_sub(0x2020_2020_2020_2020)) & !chunk & HIGH != 0 {
948        return true;
949    }
950    // Any byte == 0x22 (`"`).
951    let quote = chunk ^ 0x2222_2222_2222_2222;
952    if (quote.wrapping_sub(ONES)) & !quote & HIGH != 0 {
953        return true;
954    }
955    // Any byte == 0x5C (`\`).
956    let backslash = chunk ^ 0x5C5C_5C5C_5C5C_5C5C;
957    if (backslash.wrapping_sub(ONES)) & !backslash & HIGH != 0 {
958        return true;
959    }
960    // Any byte >= 0x80 (only when non-ASCII must be escaped).
961    escape_non_ascii && (chunk & HIGH) != 0
962}
963
964/// Whether `bytes` can be copied into JSON verbatim (no escaping needed).
965#[inline]
966fn can_copy_raw(bytes: &[u8], escape_non_ascii: bool) -> bool {
967    let mut i = 0;
968    let len = bytes.len();
969    while i + 8 <= len {
970        let chunk = u64::from_le_bytes(bytes[i..i + 8].try_into().unwrap());
971        if chunk_needs_escape(chunk, escape_non_ascii) {
972            return false;
973        }
974        i += 8;
975    }
976    bytes[i..].iter().all(|&byte| {
977        byte >= 0x20 && byte != b'"' && byte != b'\\' && (!escape_non_ascii || byte < 0x80)
978    })
979}
980
981/// Write `"..."` with JSON escaping into `buf`.
982///
983/// Shared by the encoder (for values and object keys) and the cross-format
984/// JSON sink; kept infallible because escaping can only write valid UTF-8
985/// into an unbounded byte buffer.
986fn write_escaped_str(buf: &mut Vec<u8>, s: &str, escape_non_ascii: bool) {
987    buf.push(b'"');
988    let bytes = s.as_bytes();
989    if can_copy_raw(bytes, escape_non_ascii) {
990        buf.extend_from_slice(bytes);
991        buf.push(b'"');
992        return;
993    }
994    let mut i = 0;
995    while i < bytes.len() {
996        let b = bytes[i];
997        match b {
998            b'"' => buf.extend_from_slice(b"\\\""),
999            b'\\' => buf.extend_from_slice(b"\\\\"),
1000            0x08 => buf.extend_from_slice(b"\\b"),
1001            0x0C => buf.extend_from_slice(b"\\f"),
1002            b'\n' => buf.extend_from_slice(b"\\n"),
1003            b'\r' => buf.extend_from_slice(b"\\r"),
1004            b'\t' => buf.extend_from_slice(b"\\t"),
1005            0x00..=0x1F => {
1006                buf.extend_from_slice(b"\\u00");
1007                const HEX: &[u8; 16] = b"0123456789abcdef";
1008                buf.push(HEX[(b >> 4) as usize]);
1009                buf.push(HEX[(b & 0xF) as usize]);
1010            }
1011            _ if escape_non_ascii && b >= 0x80 => {
1012                let ch = s[i..].chars().next().expect("valid utf-8");
1013                write_unicode_escape(buf, ch);
1014                i += ch.len_utf8();
1015                continue;
1016            }
1017            _ => buf.push(b),
1018        }
1019        i += 1;
1020    }
1021    buf.push(b'"');
1022}
1023
1024/// Write a char as `\uXXXX` (surrogate pair when needed).
1025fn write_unicode_escape(buf: &mut Vec<u8>, ch: char) {
1026    fn hex4(buf: &mut Vec<u8>, cp: u32) {
1027        buf.extend_from_slice(b"\\u");
1028        const HEX: &[u8; 16] = b"0123456789abcdef";
1029        buf.push(HEX[((cp >> 12) & 0xF) as usize]);
1030        buf.push(HEX[((cp >> 8) & 0xF) as usize]);
1031        buf.push(HEX[((cp >> 4) & 0xF) as usize]);
1032        buf.push(HEX[(cp & 0xF) as usize]);
1033    }
1034    let cp = ch as u32;
1035    if cp <= 0xFFFF {
1036        hex4(buf, cp);
1037    } else {
1038        let v = cp - 0x10000;
1039        hex4(buf, 0xD800 + (v >> 10));
1040        hex4(buf, 0xDC00 + (v & 0x3FF));
1041    }
1042}
1043
1044/// Two decimal digits per slot: `DIGITS2[10 * a + b]` is the byte pair
1045/// `"ab"`. Integer output consumes one 100-division (a single hardware
1046/// `div` when LLVM pairs it with the `% 100`) per *two* digits instead of
1047/// one `div` per digit, halving the division count on the hot path.
1048static DIGITS2: &[u8; 200] = b"00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899";
1049
1050/// Integer output using a stack buffer (no allocation).
1051///
1052/// The `u64` path is deliberately separate from the `u128` path: widening a
1053/// `u64` to `u128` and dividing forces LLVM to emit a compiler-rt
1054/// `__udivti3` libcall on x86-64 (u128 division has no single hardware
1055/// instruction), several times slower than the native `u64` `div`. Integer
1056/// values dominate JSON payloads, so the native-width path is the hot one.
1057fn write_u64_into(buf: &mut Vec<u8>, mut value: u64) {
1058    // Fast single-digit path for the most common small values: no table
1059    // load, no pair-cleanup branch.
1060    if value < 10 {
1061        buf.push(b'0' + value as u8);
1062        return;
1063    }
1064    let mut digits = [0_u8; 20];
1065    let mut cursor = digits.len();
1066    while value >= 100 {
1067        let r = (value % 100) as usize;
1068        value /= 100;
1069        cursor -= 2;
1070        digits[cursor] = DIGITS2[2 * r];
1071        digits[cursor + 1] = DIGITS2[2 * r + 1];
1072    }
1073    // One full pair (10..=99) or a single leading digit remains.
1074    if value >= 10 {
1075        let r = value as usize;
1076        cursor -= 2;
1077        digits[cursor] = DIGITS2[2 * r];
1078        digits[cursor + 1] = DIGITS2[2 * r + 1];
1079    } else {
1080        cursor -= 1;
1081        digits[cursor] = b'0' + value as u8;
1082    }
1083    buf.extend_from_slice(&digits[cursor..]);
1084}
1085
1086fn write_i64_into(buf: &mut Vec<u8>, value: i64) {
1087    if value < 0 {
1088        buf.push(b'-');
1089        write_u64_into(buf, value.wrapping_neg() as u64);
1090    } else {
1091        write_u64_into(buf, value as u64);
1092    }
1093}
1094
1095/// Integer output for the wide (128-bit) path only.
1096fn write_unsigned_integer_into(buf: &mut Vec<u8>, mut value: u128) {
1097    let mut digits = [0_u8; 39];
1098    let mut cursor = digits.len();
1099    while value >= 100 {
1100        let r = (value % 100) as usize;
1101        value /= 100;
1102        cursor -= 2;
1103        digits[cursor] = DIGITS2[2 * r];
1104        digits[cursor + 1] = DIGITS2[2 * r + 1];
1105    }
1106    if value >= 10 {
1107        let r = value as usize;
1108        cursor -= 2;
1109        digits[cursor] = DIGITS2[2 * r];
1110        digits[cursor + 1] = DIGITS2[2 * r + 1];
1111    } else {
1112        cursor -= 1;
1113        digits[cursor] = b'0' + value as u8;
1114    }
1115    buf.extend_from_slice(&digits[cursor..]);
1116}
1117
1118fn write_signed_integer_into(buf: &mut Vec<u8>, value: i128) {
1119    if value < 0 {
1120        buf.push(b'-');
1121        write_unsigned_integer_into(buf, value.wrapping_neg() as u128);
1122    } else {
1123        write_unsigned_integer_into(buf, value as u128);
1124    }
1125}
1126
1127struct FloatBuffer {
1128    bytes: [u8; 64],
1129    len: usize,
1130}
1131
1132impl FloatBuffer {
1133    fn new() -> Self {
1134        FloatBuffer {
1135            bytes: [0; 64],
1136            len: 0,
1137        }
1138    }
1139
1140    fn as_bytes(&self) -> &[u8] {
1141        &self.bytes[..self.len]
1142    }
1143}
1144
1145impl fmt::Write for FloatBuffer {
1146    fn write_str(&mut self, value: &str) -> fmt::Result {
1147        let end = self.len.checked_add(value.len()).ok_or(fmt::Error)?;
1148        let output = self.bytes.get_mut(self.len..end).ok_or(fmt::Error)?;
1149        output.copy_from_slice(value.as_bytes());
1150        self.len = end;
1151        Ok(())
1152    }
1153}
1154
1155fn write_float_into<T: fmt::Display>(buf: &mut Vec<u8>, value: T) -> Result<()> {
1156    let mut formatted = FloatBuffer::new();
1157    core::write!(&mut formatted, "{value}")
1158        .map_err(|_| Error::custom("internal float formatting buffer exhausted"))?;
1159    let bytes = formatted.as_bytes();
1160    buf.extend_from_slice(bytes);
1161    if !bytes.iter().any(|byte| matches!(byte, b'.' | b'e' | b'E')) {
1162        buf.extend_from_slice(b".0");
1163    }
1164    Ok(())
1165}
1166
1167// ---------------------------------------------------------------------------
1168// std / alloc NsonSchema + NsonSerialize implementations
1169// ---------------------------------------------------------------------------
1170
1171macro_rules! impl_scalar {
1172    ($($t:ty => $schema:expr => $write:ident => $cast_to:ty),* $(,)?) => {$(
1173        impl NsonSchema for $t {
1174            const SCHEMA: TypeSchema = $schema;
1175        }
1176        impl NsonSerialize for $t {
1177            fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1178                e.$write(*self as $cast_to)
1179            }
1180        }
1181    )*};
1182}
1183
1184impl_scalar! {
1185    bool => TypeSchema::Bool => write_bool => bool,
1186    i8 => TypeSchema::I8 => write_i8 => i8,
1187    i16 => TypeSchema::I16 => write_i16 => i16,
1188    i32 => TypeSchema::I32 => write_i32 => i32,
1189    i64 => TypeSchema::I64 => write_i64 => i64,
1190    i128 => TypeSchema::I128 => write_i128 => i128,
1191    isize => TypeSchema::Isize => write_i64 => i64,
1192    u8 => TypeSchema::U8 => write_u8 => u8,
1193    u16 => TypeSchema::U16 => write_u16 => u16,
1194    u32 => TypeSchema::U32 => write_u32 => u32,
1195    u64 => TypeSchema::U64 => write_u64 => u64,
1196    u128 => TypeSchema::U128 => write_u128 => u128,
1197    usize => TypeSchema::Usize => write_u64 => u64,
1198    f32 => TypeSchema::F32 => write_f32 => f32,
1199    f64 => TypeSchema::F64 => write_f64 => f64,
1200}
1201
1202impl NsonSchema for char {
1203    const SCHEMA: TypeSchema = TypeSchema::Char;
1204}
1205impl NsonSerialize for char {
1206    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1207        e.write_char(*self)
1208    }
1209}
1210
1211impl NsonSchema for str {
1212    const SCHEMA: TypeSchema = TypeSchema::Str;
1213}
1214impl NsonSerialize for str {
1215    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1216        e.write_str(self)
1217    }
1218}
1219
1220impl NsonSchema for String {
1221    const SCHEMA: TypeSchema = TypeSchema::Str;
1222}
1223impl NsonSerialize for String {
1224    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1225        e.write_str(self)
1226    }
1227}
1228
1229impl<'a> NsonSchema for Cow<'a, str> {
1230    const SCHEMA: TypeSchema = TypeSchema::Str;
1231}
1232impl<'a> NsonSerialize for Cow<'a, str> {
1233    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1234        e.write_str(self)
1235    }
1236}
1237
1238impl<T: NsonSerialize + ?Sized> NsonSchema for Box<T> {
1239    const SCHEMA: TypeSchema = T::SCHEMA;
1240}
1241impl<T: NsonSerialize + ?Sized> NsonSerialize for Box<T> {
1242    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1243        T::nextencode(self, e)
1244    }
1245}
1246
1247impl<T: NsonSerialize + ?Sized> NsonSchema for &T {
1248    const SCHEMA: TypeSchema = T::SCHEMA;
1249}
1250impl<T: NsonSerialize + ?Sized> NsonSerialize for &T {
1251    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1252        T::nextencode(*self, e)
1253    }
1254}
1255
1256impl<T: NsonSerialize + ?Sized> NsonSchema for &mut T {
1257    const SCHEMA: TypeSchema = T::SCHEMA;
1258}
1259impl<T: NsonSerialize + ?Sized> NsonSerialize for &mut T {
1260    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1261        T::nextencode(&**self, e)
1262    }
1263}
1264
1265impl<T: NsonSerialize> NsonSchema for Rc<T> {
1266    const SCHEMA: TypeSchema = T::SCHEMA;
1267}
1268impl<T: NsonSerialize> NsonSerialize for Rc<T> {
1269    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1270        T::nextencode(self, e)
1271    }
1272}
1273
1274impl<T: NsonSerialize> NsonSchema for Arc<T> {
1275    const SCHEMA: TypeSchema = T::SCHEMA;
1276}
1277impl<T: NsonSerialize> NsonSerialize for Arc<T> {
1278    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1279        T::nextencode(self, e)
1280    }
1281}
1282
1283impl<T: NsonSerialize + Copy> NsonSchema for Cell<T> {
1284    const SCHEMA: TypeSchema = T::SCHEMA;
1285}
1286impl<T: NsonSerialize + Copy> NsonSerialize for Cell<T> {
1287    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1288        T::nextencode(&self.get(), e)
1289    }
1290}
1291
1292impl<T: NsonSerialize> NsonSchema for RefCell<T> {
1293    const SCHEMA: TypeSchema = T::SCHEMA;
1294}
1295impl<T: NsonSerialize> NsonSerialize for RefCell<T> {
1296    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1297        T::nextencode(&self.borrow(), e)
1298    }
1299}
1300
1301impl<T: NsonSerialize> NsonSchema for Option<T> {
1302    const SCHEMA: TypeSchema = TypeSchema::Optional(&T::SCHEMA);
1303}
1304impl<T: NsonSerialize> NsonSerialize for Option<T> {
1305    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1306        match self {
1307            Some(v) => {
1308                e.write_some()?;
1309                T::nextencode(v, e)
1310            }
1311            None => e.write_none(),
1312        }
1313    }
1314}
1315
1316impl<T: NsonSerialize, E: NsonSerialize> NsonSchema for core::result::Result<T, E> {
1317    const SCHEMA: TypeSchema = TypeSchema::Enum(&crate::schema::EnumSchema {
1318        name: "Result",
1319        tag: None,
1320        content: None,
1321        untagged: false,
1322        default_tag: "type",
1323        variants: &[
1324            crate::schema::VariantSchema {
1325                name: "Ok",
1326                orig: "Ok",
1327                ty: T::SCHEMA,
1328            },
1329            crate::schema::VariantSchema {
1330                name: "Err",
1331                orig: "Err",
1332                ty: E::SCHEMA,
1333            },
1334        ],
1335    });
1336}
1337impl<T: NsonSerialize, E: NsonSerialize> NsonSerialize for core::result::Result<T, E> {
1338    fn nextencode<__E: FormatEncoder>(&self, e: &mut __E) -> Result<(), __E::Error> {
1339        e.begin_object()?;
1340        match self {
1341            Ok(v) => {
1342                e.key("Ok")?;
1343                T::nextencode(v, e)?;
1344            }
1345            Err(v) => {
1346                e.key("Err")?;
1347                E::nextencode(v, e)?;
1348            }
1349        }
1350        e.end_object()
1351    }
1352}
1353
1354impl<T: NsonSerialize> NsonSchema for Vec<T> {
1355    const SCHEMA: TypeSchema = TypeSchema::Seq(&T::SCHEMA);
1356}
1357impl<T: NsonSerialize> NsonSerialize for Vec<T> {
1358    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1359        e.begin_array()?;
1360        for item in self {
1361            e.separator()?;
1362            T::nextencode(item, e)?;
1363        }
1364        e.end_array()
1365    }
1366}
1367
1368impl<T: NsonSerialize> NsonSchema for [T] {
1369    const SCHEMA: TypeSchema = TypeSchema::Seq(&T::SCHEMA);
1370}
1371impl<T: NsonSerialize> NsonSerialize for [T] {
1372    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1373        e.begin_array()?;
1374        for item in self {
1375            e.separator()?;
1376            T::nextencode(item, e)?;
1377        }
1378        e.end_array()
1379    }
1380}
1381
1382impl<T: NsonSerialize, const N: usize> NsonSchema for [T; N] {
1383    const SCHEMA: TypeSchema = TypeSchema::Seq(&T::SCHEMA);
1384}
1385impl<T: NsonSerialize, const N: usize> NsonSerialize for [T; N] {
1386    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1387        e.begin_array()?;
1388        for item in self {
1389            e.separator()?;
1390            T::nextencode(item, e)?;
1391        }
1392        e.end_array()
1393    }
1394}
1395
1396// ---------------------------------------------------------------------------
1397// byte sequences use the dedicated `write_bytes` / `bytes()` event primitives.
1398//
1399// As in serde, `Vec<u8>` / `&[u8]` / `[u8; N]` deliberately keep the generic
1400// sequence implementation (an array of `u8`), so no conflicting impls arise.
1401// Types that want a native compact byte string on the wire use the
1402// [`crate::Bytes`] wrapper, which routes through `write_bytes`.
1403// ---------------------------------------------------------------------------
1404
1405impl<T: NsonSerialize> NsonSchema for VecDeque<T> {
1406    const SCHEMA: TypeSchema = TypeSchema::Seq(&T::SCHEMA);
1407}
1408impl<T: NsonSerialize> NsonSerialize for VecDeque<T> {
1409    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1410        e.begin_array()?;
1411        for item in self {
1412            e.separator()?;
1413            T::nextencode(item, e)?;
1414        }
1415        e.end_array()
1416    }
1417}
1418
1419impl<T: NsonSerialize> NsonSchema for LinkedList<T> {
1420    const SCHEMA: TypeSchema = TypeSchema::Seq(&T::SCHEMA);
1421}
1422impl<T: NsonSerialize> NsonSerialize for LinkedList<T> {
1423    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1424        e.begin_array()?;
1425        for item in self {
1426            e.separator()?;
1427            T::nextencode(item, e)?;
1428        }
1429        e.end_array()
1430    }
1431}
1432
1433impl<T: NsonSerialize> NsonSchema for BTreeSet<T> {
1434    const SCHEMA: TypeSchema = TypeSchema::Seq(&T::SCHEMA);
1435}
1436impl<T: NsonSerialize> NsonSerialize for BTreeSet<T> {
1437    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1438        e.begin_array()?;
1439        for item in self {
1440            e.separator()?;
1441            T::nextencode(item, e)?;
1442        }
1443        e.end_array()
1444    }
1445}
1446
1447impl<T: NsonSerialize + Ord> NsonSchema for BinaryHeap<T> {
1448    const SCHEMA: TypeSchema = TypeSchema::Seq(&T::SCHEMA);
1449}
1450impl<T: NsonSerialize + Ord> NsonSerialize for BinaryHeap<T> {
1451    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1452        e.begin_array()?;
1453        for item in self {
1454            e.separator()?;
1455            T::nextencode(item, e)?;
1456        }
1457        e.end_array()
1458    }
1459}
1460
1461impl<K: NsonSerialize, V: NsonSerialize> NsonSchema for BTreeMap<K, V> {
1462    const SCHEMA: TypeSchema = TypeSchema::Map(&V::SCHEMA);
1463}
1464impl<K: NsonSerialize, V: NsonSerialize> NsonSerialize for BTreeMap<K, V> {
1465    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1466        e.begin_object()?;
1467        for (k, v) in self {
1468            e.map_key(k)?;
1469            V::nextencode(v, e)?;
1470        }
1471        e.end_object()
1472    }
1473}
1474
1475#[cfg(feature = "std")]
1476impl<K: NsonSerialize + core::hash::Hash + Eq, V: NsonSerialize> NsonSchema
1477    for std::collections::HashMap<K, V>
1478{
1479    const SCHEMA: TypeSchema = TypeSchema::Map(&V::SCHEMA);
1480}
1481#[cfg(feature = "std")]
1482impl<K: NsonSerialize + core::hash::Hash + Eq, V: NsonSerialize> NsonSerialize
1483    for std::collections::HashMap<K, V>
1484{
1485    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1486        e.begin_object()?;
1487        for (k, v) in self {
1488            e.map_key(k)?;
1489            V::nextencode(v, e)?;
1490        }
1491        e.end_object()
1492    }
1493}
1494
1495#[cfg(feature = "std")]
1496impl<T: NsonSerialize + core::hash::Hash + Eq> NsonSchema for std::collections::HashSet<T> {
1497    const SCHEMA: TypeSchema = TypeSchema::Seq(&T::SCHEMA);
1498}
1499#[cfg(feature = "std")]
1500impl<T: NsonSerialize + core::hash::Hash + Eq> NsonSerialize for std::collections::HashSet<T> {
1501    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1502        e.begin_array()?;
1503        for item in self {
1504            e.separator()?;
1505            T::nextencode(item, e)?;
1506        }
1507        e.end_array()
1508    }
1509}
1510
1511/// Convert a map key to a string.
1512///
1513/// String-like keys keep their text; scalar keys (numbers, booleans) use
1514/// their JSON spelling as the key text (matching serde_json). The default
1515/// [`FormatEncoder::map_key`] implementation routes through this.
1516fn key_to_str<K: NsonSerialize>(k: &K) -> Result<String> {
1517    let mut encoder = Encoder::<Vec<u8>>::new(Vec::new());
1518    K::nextencode(k, &mut encoder)?;
1519    let bytes = encoder.finish()?;
1520    if bytes.first() == Some(&b'"') {
1521        let mut d = crate::de::Decoder::new(&bytes);
1522        match d.string()? {
1523            Cow::Borrowed(s) => Ok(s.to_string()),
1524            Cow::Owned(s) => Ok(s),
1525        }
1526    } else {
1527        // A scalar key: `1`, `true`, ... becomes the string `"1"`, `"true"`.
1528        String::from_utf8(bytes)
1529            .map_err(|_| Error::custom("map key must serialize to a string or scalar"))
1530    }
1531}
1532
1533// ---------------------------------------------------------------------------
1534// tuples / unit / PhantomData / common types
1535// ---------------------------------------------------------------------------
1536
1537impl NsonSchema for () {
1538    const SCHEMA: TypeSchema = TypeSchema::Unit;
1539}
1540impl NsonSerialize for () {
1541    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1542        e.write_null()
1543    }
1544}
1545
1546impl<T: ?Sized> NsonSchema for PhantomData<T> {
1547    const SCHEMA: TypeSchema = TypeSchema::Unit;
1548}
1549impl<T: ?Sized> NsonSerialize for PhantomData<T> {
1550    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1551        e.write_null()
1552    }
1553}
1554
1555impl NsonSchema for Duration {
1556    const SCHEMA: TypeSchema = TypeSchema::U128;
1557}
1558impl NsonSerialize for Duration {
1559    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1560        e.write_u128(self.as_nanos())
1561    }
1562}
1563
1564#[cfg(feature = "std")]
1565impl NsonSchema for std::path::Path {
1566    const SCHEMA: TypeSchema = TypeSchema::Str;
1567}
1568#[cfg(feature = "std")]
1569impl NsonSerialize for std::path::Path {
1570    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1571        e.write_str(&self.to_string_lossy())
1572    }
1573}
1574#[cfg(feature = "std")]
1575impl NsonSchema for std::path::PathBuf {
1576    const SCHEMA: TypeSchema = TypeSchema::Str;
1577}
1578#[cfg(feature = "std")]
1579impl NsonSerialize for std::path::PathBuf {
1580    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1581        self.as_path().nextencode(e)
1582    }
1583}
1584
1585#[cfg(feature = "std")]
1586impl NsonSchema for std::net::IpAddr {
1587    const SCHEMA: TypeSchema = TypeSchema::Str;
1588}
1589#[cfg(feature = "std")]
1590impl NsonSerialize for std::net::IpAddr {
1591    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1592        e.write_str(&self.to_string())
1593    }
1594}
1595#[cfg(feature = "std")]
1596impl NsonSchema for std::net::Ipv4Addr {
1597    const SCHEMA: TypeSchema = TypeSchema::Str;
1598}
1599#[cfg(feature = "std")]
1600impl NsonSerialize for std::net::Ipv4Addr {
1601    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1602        e.write_str(&self.to_string())
1603    }
1604}
1605#[cfg(feature = "std")]
1606impl NsonSchema for std::net::Ipv6Addr {
1607    const SCHEMA: TypeSchema = TypeSchema::Str;
1608}
1609#[cfg(feature = "std")]
1610impl NsonSerialize for std::net::Ipv6Addr {
1611    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1612        e.write_str(&self.to_string())
1613    }
1614}
1615#[cfg(feature = "std")]
1616impl NsonSchema for std::net::SocketAddr {
1617    const SCHEMA: TypeSchema = TypeSchema::Str;
1618}
1619#[cfg(feature = "std")]
1620impl NsonSerialize for std::net::SocketAddr {
1621    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1622        e.write_str(&self.to_string())
1623    }
1624}
1625
1626impl<T: NsonSerialize> NsonSchema for Range<T> {
1627    const SCHEMA: TypeSchema = TypeSchema::Tuple(&[T::SCHEMA, T::SCHEMA]);
1628}
1629impl<T: NsonSerialize> NsonSerialize for Range<T> {
1630    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1631        e.begin_array()?;
1632        e.separator()?;
1633        T::nextencode(&self.start, e)?;
1634        e.separator()?;
1635        T::nextencode(&self.end, e)?;
1636        e.end_array()
1637    }
1638}
1639
1640impl<T: NsonSerialize> NsonSchema for RangeInclusive<T> {
1641    const SCHEMA: TypeSchema = TypeSchema::Tuple(&[T::SCHEMA, T::SCHEMA]);
1642}
1643impl<T: NsonSerialize> NsonSerialize for RangeInclusive<T> {
1644    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1645        e.begin_array()?;
1646        e.separator()?;
1647        T::nextencode(self.start(), e)?;
1648        e.separator()?;
1649        T::nextencode(self.end(), e)?;
1650        e.end_array()
1651    }
1652}
1653
1654impl<T: NsonSerialize> NsonSchema for RangeFrom<T> {
1655    const SCHEMA: TypeSchema = TypeSchema::Tuple(&[T::SCHEMA]);
1656}
1657impl<T: NsonSerialize> NsonSerialize for RangeFrom<T> {
1658    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1659        e.begin_array()?;
1660        e.separator()?;
1661        T::nextencode(&self.start, e)?;
1662        e.end_array()
1663    }
1664}
1665
1666impl<T: NsonSerialize> NsonSchema for RangeTo<T> {
1667    const SCHEMA: TypeSchema = TypeSchema::Tuple(&[T::SCHEMA]);
1668}
1669impl<T: NsonSerialize> NsonSerialize for RangeTo<T> {
1670    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1671        e.begin_array()?;
1672        e.separator()?;
1673        T::nextencode(&self.end, e)?;
1674        e.end_array()
1675    }
1676}
1677
1678impl<T: NsonSerialize> NsonSchema for RangeToInclusive<T> {
1679    const SCHEMA: TypeSchema = TypeSchema::Tuple(&[T::SCHEMA]);
1680}
1681impl<T: NsonSerialize> NsonSerialize for RangeToInclusive<T> {
1682    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1683        e.begin_array()?;
1684        e.separator()?;
1685        T::nextencode(&self.end, e)?;
1686        e.end_array()
1687    }
1688}
1689
1690macro_rules! impl_atomic {
1691    ($($t:ty => $inner:ty),* $(,)?) => {$(
1692        impl NsonSchema for $t {
1693            const SCHEMA: TypeSchema = <$inner as NsonSchema>::SCHEMA;
1694        }
1695        impl NsonSerialize for $t {
1696            fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1697                let v = self.load(core::sync::atomic::Ordering::Relaxed);
1698                <$inner as NsonSerialize>::nextencode(&v, e)
1699            }
1700        }
1701    )*};
1702}
1703impl_atomic! {
1704    core::sync::atomic::AtomicBool => bool,
1705    core::sync::atomic::AtomicI8 => i8,
1706    core::sync::atomic::AtomicI16 => i16,
1707    core::sync::atomic::AtomicI32 => i32,
1708    core::sync::atomic::AtomicI64 => i64,
1709    core::sync::atomic::AtomicIsize => isize,
1710    core::sync::atomic::AtomicU8 => u8,
1711    core::sync::atomic::AtomicU16 => u16,
1712    core::sync::atomic::AtomicU32 => u32,
1713    core::sync::atomic::AtomicU64 => u64,
1714    core::sync::atomic::AtomicUsize => usize,
1715}
1716
1717macro_rules! impl_tuple_ser {
1718    ($(($first:ident : $First:ident $(, $i:ident : $T:ident)*)),* $(,)?) => {$(
1719        impl<$First: NsonSerialize $(, $T: NsonSerialize)*> NsonSchema for ($First, $( $T, )*) {
1720            const SCHEMA: TypeSchema = TypeSchema::Tuple(&[$First::SCHEMA, $( $T::SCHEMA, )*]);
1721        }
1722        impl<$First: NsonSerialize $(, $T: NsonSerialize)*> NsonSerialize for ($First, $( $T, )*) {
1723            #[allow(non_snake_case)]
1724            fn nextencode<__E: FormatEncoder>(&self, e: &mut __E) -> Result<(), __E::Error> {
1725                let ($first, $( $i, )*) = self;
1726                e.begin_array()?;
1727                e.separator()?;
1728                $First::nextencode($first, e)?;
1729                $(
1730                    e.separator()?;
1731                    $T::nextencode($i, e)?;
1732                )*
1733                e.end_array()
1734            }
1735        }
1736    )*};
1737}
1738
1739impl_tuple_ser! {
1740    (a: A),
1741    (a: A, b: B),
1742    (a: A, b: B, c: C),
1743    (a: A, b: B, c: C, d: D),
1744    (a: A, b: B, c: C, d: D, e: E),
1745    (a: A, b: B, c: C, d: D, e: E, f: F),
1746    (a: A, b: B, c: C, d: D, e: E, f: F, g: G),
1747    (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H),
1748    (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I),
1749    (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J),
1750    (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K),
1751    (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K, l: L),
1752}
1753
1754// ---------------------------------------------------------------------------
1755// Number / Map / Value
1756// ---------------------------------------------------------------------------
1757
1758impl NsonSchema for Number {
1759    const SCHEMA: TypeSchema = TypeSchema::Opaque;
1760}
1761impl NsonSerialize for Number {
1762    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1763        e.write_number(self)
1764    }
1765}
1766
1767impl NsonSchema for Map {
1768    const SCHEMA: TypeSchema = TypeSchema::Map(&TypeSchema::Opaque);
1769}
1770impl NsonSerialize for Map {
1771    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1772        e.begin_object()?;
1773        for (k, v) in self.iter() {
1774            e.key(k)?;
1775            NsonSerialize::nextencode(v, e)?;
1776        }
1777        e.end_object()
1778    }
1779}
1780
1781impl NsonSchema for Value {
1782    const SCHEMA: TypeSchema = TypeSchema::Opaque;
1783}
1784impl NsonSerialize for Value {
1785    fn nextencode<E: FormatEncoder>(&self, e: &mut E) -> Result<(), E::Error> {
1786        match self {
1787            Value::Null => e.write_null(),
1788            Value::Bool(b) => e.write_bool(*b),
1789            Value::Number(n) => e.write_number(n),
1790            Value::String(s) => e.write_str(s),
1791            Value::Array(a) => {
1792                e.begin_array()?;
1793                for v in a {
1794                    e.separator()?;
1795                    NsonSerialize::nextencode(v, e)?;
1796                }
1797                e.end_array()
1798            }
1799            Value::Object(m) => NsonSerialize::nextencode(m, e),
1800        }
1801    }
1802}
1803
1804#[cfg(test)]
1805mod tests {
1806    use super::*;
1807
1808    #[test]
1809    fn integer_formatting_basics() {
1810        let mut buf = Vec::new();
1811        write_unsigned_integer_into(&mut buf, 0);
1812        assert_eq!(buf, b"0");
1813        let mut buf = Vec::new();
1814        write_unsigned_integer_into(&mut buf, 12345);
1815        assert_eq!(buf, b"12345");
1816        let mut buf = Vec::new();
1817        write_unsigned_integer_into(&mut buf, u64::MAX as u128);
1818        assert_eq!(buf, b"18446744073709551615");
1819        let mut buf = Vec::new();
1820        write_signed_integer_into(&mut buf, i128::MIN);
1821        assert_eq!(buf, b"-170141183460469231731687303715884105728");
1822    }
1823
1824    #[test]
1825    fn native_width_integer_formatting_matches_wide_path() {
1826        // The native u64/i64 path must produce byte-identical output to the
1827        // u128 path for every value in range (including signs and extremes).
1828        for value in [
1829            0_u64,
1830            1,
1831            9,
1832            10,
1833            11,
1834            99,
1835            100,
1836            101,
1837            999,
1838            1000,
1839            1001,
1840            9999,
1841            10000,
1842            u64::MAX,
1843            u64::MAX - 1,
1844            123_456_789_012_345,
1845        ] {
1846            let mut native = Vec::new();
1847            write_u64_into(&mut native, value);
1848            let mut wide = Vec::new();
1849            write_unsigned_integer_into(&mut wide, value as u128);
1850            assert_eq!(native, wide, "u64 {value}");
1851        }
1852        for value in [
1853            i64::MIN,
1854            i64::MIN + 1,
1855            -1_i64,
1856            -10,
1857            -11,
1858            -99,
1859            -100,
1860            -999,
1861            -1000,
1862            i64::MAX,
1863            0_i64,
1864        ] {
1865            let mut native = Vec::new();
1866            write_i64_into(&mut native, value);
1867            let mut wide = Vec::new();
1868            write_signed_integer_into(&mut wide, value as i128);
1869            assert_eq!(native, wide, "i64 {value}");
1870        }
1871        // The two-digit table itself must be exactly "00"..="99".
1872        assert_eq!(DIGITS2.len(), 200);
1873        for value in 0..100u8 {
1874            assert_eq!(
1875                &DIGITS2[2 * value as usize..2 * value as usize + 2],
1876                &[b'0' + value / 10, b'0' + value % 10],
1877                "DIGITS2[{value}]"
1878            );
1879        }
1880    }
1881
1882    #[test]
1883    fn string_escaping() {
1884        let mut e = Encoder::<_, true>::new(Vec::new());
1885        e.write_str("\"\\\n\t\u{1}\u{1f4a9}").unwrap();
1886        let out = e.finish().unwrap();
1887        assert_eq!(out, b"\"\\\"\\\\\\n\\t\\u0001\xf0\x9f\x92\xa9\"");
1888    }
1889
1890    #[test]
1891    fn escape_non_ascii() {
1892        let mut e = Encoder::<_, true>::with_config(
1893            Vec::new(),
1894            EncodeConfig::default().escape_non_ascii(true),
1895        );
1896        e.write_str("\u{e9}\u{1f4a9}").unwrap();
1897        let out = e.finish().unwrap();
1898        assert_eq!(out, b"\"\\u00e9\\ud83d\\udca9\"");
1899    }
1900
1901    #[test]
1902    fn non_finite_errors() {
1903        let mut e = Encoder::<_, true>::new(Vec::new());
1904        assert!(e.write_f64(f64::NAN).is_err());
1905        let mut e = Encoder::<_, true>::new(Vec::new());
1906        assert!(e.write_f64(f64::INFINITY).is_err());
1907    }
1908
1909    #[test]
1910    fn f32_uses_its_own_shortest_representation() {
1911        let mut encoder = Encoder::<_, true>::new(Vec::new());
1912        encoder.write_f32(1.2_f32).unwrap();
1913        assert_eq!(encoder.finish().unwrap(), b"1.2");
1914    }
1915
1916    #[test]
1917    fn pretty_roundtrip() {
1918        let mut e = Encoder::<_, true>::with_config(Vec::new(), EncodeConfig::pretty());
1919        e.begin_object().unwrap();
1920        e.key("a").unwrap();
1921        e.write_i64(1).unwrap();
1922        e.key("b").unwrap();
1923        e.begin_array().unwrap();
1924        e.separator().unwrap();
1925        e.write_null().unwrap();
1926        e.end_array().unwrap();
1927        e.end_object().unwrap();
1928        let out = String::from_utf8(e.finish().unwrap()).unwrap();
1929        assert_eq!(out, "{\n  \"a\": 1,\n  \"b\": [\n    null\n  ]\n}");
1930    }
1931
1932    #[test]
1933    fn rejects_invalid_encoding_event_order() {
1934        let mut encoder = Encoder::<_, true>::new(Vec::new());
1935        assert!(encoder.end_array().is_err());
1936
1937        let mut encoder = Encoder::<_, true>::new(Vec::new());
1938        encoder.begin_array().unwrap();
1939        assert!(encoder.write_null().is_err());
1940        assert!(encoder.end_object().is_err());
1941
1942        let mut encoder = Encoder::<_, true>::new(Vec::new());
1943        encoder.begin_object().unwrap();
1944        encoder.key("pending").unwrap();
1945        assert!(encoder.end_object().is_err());
1946
1947        let mut encoder = Encoder::<_, true>::new(Vec::new());
1948        encoder.write_null().unwrap();
1949        assert!(encoder.write_bool(true).is_err());
1950
1951        let encoder = Encoder::<_, true>::new(Vec::new());
1952        assert!(encoder.finish().is_err());
1953    }
1954}