Skip to main content

JsonWrite

Trait JsonWrite 

Source
pub trait JsonWrite {
    type Error;

Show 15 methods // Required methods fn write_byte(&mut self, b: u8) -> Result<(), Self::Error>; fn write_str_raw(&mut self, s: &str) -> Result<(), Self::Error>; fn write_float_f64(&mut self, f: f64) -> Result<(), Self::Error>; // Provided methods fn reserve_hint(&mut self, _additional: usize) { ... } unsafe fn write_byte_unchecked(&mut self, b: u8) -> Result<(), Self::Error> { ... } fn write_escaped_str(&mut self, s: &str) -> Result<(), Self::Error> { ... } fn write_raw_bytes(&mut self, b: &[u8]) -> Result<(), Self::Error> { ... } fn write_int_i64(&mut self, n: i64) -> Result<(), Self::Error> { ... } fn write_int_u64(&mut self, n: u64) -> Result<(), Self::Error> { ... } fn write_int_i128(&mut self, n: i128) -> Result<(), Self::Error> { ... } fn write_int_u128(&mut self, n: u128) -> Result<(), Self::Error> { ... } unsafe fn write_float_f64_unchecked( &mut self, f: f64, ) -> Result<(), Self::Error> { ... } unsafe fn write_float_f64_unchecked_finite( &mut self, f: f64, ) -> Result<(), Self::Error> { ... } unsafe fn write_float_f64_taint( &mut self, f: f64, ) -> Result<(), Self::Error> { ... } fn take_nonfinite_taint(&mut self) -> u64 { ... }
}
Expand description

Output sink for ToJson impls.

Implementors expose per-primitive writers so the trait impls below can avoid the core::fmt machinery. The default integer/float methods land on write_str_raw after formatting into a small stack buffer, but implementations that can write directly (e.g. StringSink’s integer LUT) override them.

Required Associated Types§

Source

type Error

Sink-specific error type. StringSink uses core::convert::Infallible for the byte/string writes; the typed-level to_string entry point widens to crate::Error so non-finite floats can surface.

Required Methods§

Source

fn write_byte(&mut self, b: u8) -> Result<(), Self::Error>

Append a single ASCII byte. Used for structural punctuation ({, }, [, ], ,, :, ").

Source

fn write_str_raw(&mut self, s: &str) -> Result<(), Self::Error>

Append a &str verbatim. Caller is responsible for any escaping — this is the structural / pre-escaped path. For user string payloads, call Self::write_escaped_str instead.

Source

fn write_float_f64(&mut self, f: f64) -> Result<(), Self::Error>

Write a finite f64 as a JSON number. Non-finite inputs (inf, -inf, NaN) have no JSON representation; sinks reject them via their Self::Error type.

The default routes through core::fmt::Write after stack-buffer formatting via format! — this is the “good enough” path that works for any sink. Sinks that want shortest-round-trip output without fmt overhead override with a direct ryu call.

Provided Methods§

Source

fn reserve_hint(&mut self, _additional: usize)

Hint that at least additional more bytes will be written. Sinks backed by a growable buffer (like ByteSink) can amortize capacity growth across a known-size sequence; sinks without a reservation concept treat this as a no-op.

Hot path: the array writer in this module calls this once at the start of a slice/Vec serialization so per-element reserve calls become predictable no-ops.

Source

unsafe fn write_byte_unchecked(&mut self, b: u8) -> Result<(), Self::Error>

Append a single ASCII byte WITHOUT a per-write capacity check.

§Safety

The caller MUST have previously called Self::reserve_hint with at least enough bytes to cover this write plus all subsequent writes up to the next reserve_hint (or the end of writing). Sinks that don’t track a tail capacity (e.g. fmt::Write-backed) fall back to the safe write_byte.

Why this exists: under random f64 inputs the per-element capacity-check branch in Vec::push at the comma site mispredicts at ~13% in perf record -e branch-misses — the single largest mispredict source in the array hot loop. Hoisting the check via reserve_hint and emitting the byte unchecked removes that branch entirely from the inner loop.

Default impl forwards to write_byte (safe but checked) so non-ByteSink sinks aren’t required to opt in.

§Safety contract example (matches what write_array does)
w.reserve_hint(n * MAX + brackets_and_commas);
for _ in 0..count {
    // SAFETY: reserve_hint covered all of these.
    unsafe { w.write_byte_unchecked(b','); }
    w.write_int_u64(...);  // also covered by reserve_hint
}
Source

fn write_escaped_str(&mut self, s: &str) -> Result<(), Self::Error>

Append a JSON-quoted, escaped string (including the surrounding " characters). The default impl escapes one byte at a time through write_byte; sinks with bulk-write capability (like StringSink) override with a literal-run fast path.

Source

fn write_raw_bytes(&mut self, b: &[u8]) -> Result<(), Self::Error>

Append a byte slice whose contents are known-valid UTF-8.

Used by macro-generated code to fuse adjacent structural literals (e.g. b"{\"id\":") into a single write. The default routes through Self::write_str_raw; byte-oriented sinks like ByteSink override to avoid the &str conversion.

Source

fn write_int_i64(&mut self, n: i64) -> Result<(), Self::Error>

Write a signed 64-bit integer as a JSON number.

Source

fn write_int_u64(&mut self, n: u64) -> Result<(), Self::Error>

Write an unsigned 64-bit integer as a JSON number.

Source

fn write_int_i128(&mut self, n: i128) -> Result<(), Self::Error>

Write a signed 128-bit integer as a JSON number.

Source

fn write_int_u128(&mut self, n: u128) -> Result<(), Self::Error>

Write an unsigned 128-bit integer as a JSON number.

Source

unsafe fn write_float_f64_unchecked( &mut self, f: f64, ) -> Result<(), Self::Error>

Write a finite f64 ASSUMING the caller has reserved at least f64::MAX_SERIALIZED_LEN (32) bytes of sink capacity. Skips the per-call cap check in Vec::extend_from_slice — the second-largest mispredict source after the comma Vec::push.

Default impl forwards to write_float_f64. ByteSink overrides with a raw-pointer write directly into the Vec’s reserved tail.

§Safety

f64::MAX_SERIALIZED_LEN (32) bytes of sink capacity must be guaranteed available before this call. Used by [f64]:: write_json_in_reserved after [T]::write_json’s reserve_hint.

Source

unsafe fn write_float_f64_unchecked_finite( &mut self, f: f64, ) -> Result<(), Self::Error>

Like write_float_f64_unchecked, but additionally requires the caller to have validated that f is finite. The per-element finiteness branch in the bench’s hot loop was the dominant remaining mispredict source after the cap-check elimination; hoisting validation to a one-shot pre-scan over the whole slice removes that branch from the inner loop entirely.

Default impl forwards to write_float_f64_unchecked. ByteSink overrides with the finite-known float path.

§Safety

All preconditions of write_float_f64_unchecked, plus f must be finite. Used after a successful [f64]::pre_validate_slice.

Source

unsafe fn write_float_f64_taint(&mut self, f: f64) -> Result<(), Self::Error>

Per-element float write that branchlessly tolerates non-finite input. Tainted bytes (junk ASCII for non-finite values) land in the sink; the caller is expected to query the sink’s take_nonfinite_taint() once at the end of the slice and turn a non-zero result into a typed error.

This avoids both the per-element finiteness branch AND the pre-scan pass that hoisted it out of the loop in the previous design (the SIMD-vectorised pand/pcmpeqd scan was costing ~20% of total cycles per perf record -c cycles).

Default impl forwards to write_float_f64_unchecked and emits a dummy taint of 0 — sinks without taint tracking should never be driven through this path.

§Safety

MAX_SERIALIZED_LEN (32) bytes of sink capacity must be available.

Source

fn take_nonfinite_taint(&mut self) -> u64

Read and clear the accumulated non-finite taint from the sink. Returns 0 for sinks without taint tracking. The array writer queries this once after a batch of write_float_f64_taint calls; a non-zero result means at least one input was inf/NaN and the call must return Err(NonFiniteFloat).

Implementors§

Source§

impl JsonWrite for ByteSink<'_>

Available on crate feature alloc only.
Source§

impl JsonWrite for PrettyStringSink<'_>

Available on crate feature alloc only.
Source§

impl JsonWrite for StringSink<'_>

Available on crate feature alloc only.
Source§

impl<W: Write + ?Sized> JsonWrite for FmtWriteSink<'_, W>

Available on crate feature alloc only.
Source§

impl<W: Write + ?Sized> JsonWrite for IoWriteSink<'_, W>

Available on crate feature std only.