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).

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

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.