Skip to main content

Crate nextjson

Crate nextjson 

Source
Expand description

§NextJson

A dependency-free, no_std + alloc data-contract engine for Rust, built for controlled protocols and resource-constrained environments: schema-first (a type describes its contract via const SCHEMA), multi-format (16 wire formats behind one implementation), and reuse-first (checked DecodeSlot decode straight into your fields).

The public native contracts are NsonSerialize::nextencode, NsonDeserialize::nextdecode_into, nextencode, and nextdecode. JSON and the JSON-compatible CBOR profile can also be relayed through the format-neutral cross_format::EventSink protocol without constructing an intermediate Value tree.

Beyond encode/decode, the schema tree powers two contract-level features:

  • validate — schema-declared safety policy (string / collection / numeric limits, deny_unknown_fields, max_depth, sensitive) enforced on a decoded Value;
  • compat — version-compatibility checking: diff two TypeSchemas and report every change that can break an old reader consuming new data or a new reader consuming old data.

§Quick start

let expected = (7_u64, "NextJson", vec![1_i32, 2, 3]);
let json = nextjson::nextencode(&expected)?;
let actual: (u64, &str, Vec<i32>) = nextjson::nextdecode(&json)?;
assert_eq!(actual, expected);

§Cross-format relay

use nextjson::cross_format;

let source = br#"{"name":"NextJson","values":[1,2,3]}"#;
let cbor = cross_format::json_to_cbor(source)?;
let json = cross_format::cbor_to_json(&cbor)?;
let value: nextjson::Value = nextjson::nextdecode(&json)?;
assert_eq!(value["name"], nextjson::Value::from("NextJson"));

§Zero-copy boundary

Unescaped JSON strings and definite-length CBOR text strings borrow their input ranges. Escaped JSON and indefinite-length CBOR text must materialize decoded UTF-8. Encoding always writes new output bytes. The library does not describe those required copies as zero-copy.

§Features

  • std (default): standard I/O adapters and standard-library integrations.
  • derive (default): repository-owned NsonSerialize and NsonDeserialize procedural macros.
  • simd (opt-in): architecture-accelerated JSON string scanning. On x86-64 this uses SSE2 (always present) plus AVX2 after a runtime CPUID check; on aarch64 it uses NEON; everywhere else (and whenever simd is off) a portable 8/16-byte register-width SWAR fallback is used. The unsafe code lives only in the private scan module and only when simd is enabled; default builds keep the crate-wide #![deny(unsafe_code)] with zero unsafe.

Disabling default features leaves a core + alloc implementation. The complete workspace dependency graph contains only nextjson and the local, optional nextjson-derive crate.

§Architecture

NextJson uses schema-driven derives, a unified token stream, checked decode slots, and a format-neutral cross_format::EventSink protocol. The whole workspace build graph contains only its two local crates.

The following properties are implemented directly in this repository and are enforced by its tests and build configuration:

  1. Direct dual contract - NsonSerialize::nextencode writes bytes directly; NsonDeserialize::nextdecode_into decodes into a caller-provided checked nextdecode slot, supporting memory reuse without a placeholder value.
  2. Compile-time schema - every type carries const SCHEMA: TypeSchema, a runtime-introspectable metadata tree (usable for JSON Schema generation, validation, and tooling).
  3. Schema-declared safety policy - limits (max_str_len, max_items, min / max, sensitive, max_depth, deny_unknown_fields) live in the schema and are enforced by validate on decoded values.
  4. Version-compatibility checking - compat::check diffs two TypeSchema values and reports forward / backward breaks with severity.
  5. Unified token stream - the byte-stream lexer and the content-replay reader share identical nextdecode primitives, so internally-tagged, adjacently-tagged, and untagged enums plus Value round-trips reuse one engine.
  6. Lazy single-token lookahead - the parser lexes one token at a time; unescaped strings borrow the input with zero allocation; integer parsing is hand-rolled with overflow detection.
  7. Safety boundary - the library is #![deny(unsafe_code)], including nextdecode slots and partial-initialization cleanup. no_std is fully supported: the core uses only core + alloc, with std-only types behind the std feature.
  8. Streaming cross-format relay - JSON and the JSON-compatible CBOR profile exchange borrowed structural events without an intermediate Value.
  9. One validated event protocol - every format encoder and both cross-format sinks validate container / key / value ordering through a single shared state machine, parameterized only by whether the wire format has explicit array separators (JSON does, CBOR does not). The byte lexer additionally serves typed scalar reads (number, string, bool, Option dispatch) directly from the source byte, so the token stream stays available for content replay without taxing the hot path.

§Safety and resource limits

This crate denies unsafe Rust. Decode slots use checked state, numeric conversions use checked arithmetic, and decoders cap nesting at 128 by default. Applications must still enforce total input bytes, collection sizes, CPU time, and output quotas. from_slice / from_str operate on a complete in-memory input; from_reader (std) pulls incrementally from any std::io::Read source.

See the repository’s [English README], [Chinese README], [safety model], and [benchmark protocol] for the complete supported surface and reproducibility requirements.

Re-exports§

pub use crate::compat::check;
pub use crate::compat::check_between;
pub use crate::compat::CompatIssue;
pub use crate::compat::CompatKind;
pub use crate::compat::CompatReport;
pub use crate::compat::Severity;
pub use crate::de::DecodeConfig;
pub use crate::de::DecodeSlot;
pub use crate::de::Decoder;
pub use crate::de::FormatDecoder;
pub use crate::de::NsonDeserialize;
pub use crate::de::OptionTag;
pub use crate::encoding::EncodeConfig;
pub use crate::encoding::Encoder;
pub use crate::encoding::FastEncoder;
pub use crate::error::Error;
pub use crate::error::FormatError;
pub use crate::error::Result;
pub use crate::map::Map;
pub use crate::stream::StreamDecoder;

Modules§

compat
Version-compatibility checking between two schemas.
cross_format
Dependency-free streaming interoperability between structured formats.
de
Deserialization: a unified token-stream decoder, the NsonDeserialize trait, and standard-library implementations.
encoding
Encoder configuration and construction.
error
Error model: JSON errors with precise position (line / column / offset).
formats
Dependency-free multi-format codec engine.
map
Insertion-ordered JSON object map.
stream
Streaming JSON decoding from a std::io::Read source.

Macros§

json
The json! macro: build a Value with JSON-like syntax.

Structs§

Bytes
A borrowed byte string that round-trips through the dedicated bytes path.
EnumSchema
Compile-time description of an enum.
FieldSchema
Compile-time description of a struct field.
Policy
A declared safety policy attached to a schema node.
Report
The result of a validation walk.
StructSchema
Compile-time description of a struct.
ValidateConfig
Runtime tuning for a validation walk.
VariantSchema
Compile-time description of an enum variant.
Violation
A single validation finding at a value path.

Enums§

Number
A JSON number.
TypeSchema
Compile-time description of a type’s structure.
Value
A self-describing JSON value.
ViolationKind
The kind of a single policy or shape violation.

Constants§

HARD_DEPTH_CAP
Hard ceiling on the validation recursion, applied regardless of config.

Traits§

FormatEncoder
Format-neutral emission contract implemented by every destination codec.
NsonSchema
Compile-time schema provider.
NsonSerialize
Serialization trait: nextencode Self into any FormatEncoder.
Write
A minimal byte sink.

Functions§

from_reader
Deserialize from a std::io::Read (requires the std feature).
from_slice
Deserialize from a &[u8]. The 'de lifetime allows types to borrow input.
from_str
Deserialize from a &str. The 'de lifetime allows types to borrow input.
from_value
Convert a Value into any type (owned, deserializable for any lifetime).
nextdecode
Decode one complete JSON value using the native NextJson data model.
nextencode
Encode a value into a compact JSON byte vector using the native NextJson data model.
schema_of
Get the compile-time TypeSchema of a type (runtime-introspectable).
to_io_writer
Serialize a value to a std::io::Write sink (requires the std feature).
to_json_schema
Generate a JSON Schema (draft-07 style) for any NsonSchema type.
to_string
Serialize a value into a compact JSON string.
to_string_pretty
Serialize a value into a pretty-printed JSON string.
to_value
Convert any serializable value into a Value.
to_vec
Serialize a value into a compact JSON byte vector.
to_vec_pretty
Serialize a value into a pretty-printed JSON byte vector.
to_writer
Serialize a value to any Write sink.
to_writer_pretty
Serialize a value to any Write sink with pretty printing.
validate
Validate a Value against a TypeSchema with default tuning.
validate_value
Validate a Value against the compile-time schema of T.
validate_value_with
Validate a Value against the compile-time schema of T with explicit tuning.
validate_with
Validate a Value against a TypeSchema with explicit tuning.

Derive Macros§

NsonDeserialize
Derive NextJson’s native decoding contract.
NsonSerialize
Derive NextJson’s native serialization contract and compile-time schema.