Why this exists
Two crates in the oxml
suite speak JSON-RPC: oxml-mcp over the Model Context Protocol, and
oxml-lsp over the Language Server Protocol. For a while each carried
its own copy of this file, because neither could reach the other's
private module.
A copy is fine until it is not. A defect fixed in one would not have reached the other, and nothing would have noticed — the failure mode this suite keeps finding elsewhere. It lives here instead. The LSP transport uses this crate; the MCP server now uses its SDK's JSON stack.
The extraction was worth it immediately. Moving the fuzz target
here came with a stronger assertion — that anything which parses must
survive a round trip — and it found a defect within ninety seconds that
had been in both copies: 1e999 is grammatically valid JSON, parses to
infinity, and infinity has no JSON representation, so serialising it
produced output that would not parse. It is now refused, because
writing null instead would silently change the value.
Scope
JSON-RPC messages are small and their shapes are fixed, so this
implements what those protocols need rather than everything the grammar
allows. It is not a general-purpose JSON library and does not try to
be. If you want serde, use serde — it is better at this, and
this crate exists to avoid a dependency in a specific place, not to
compete.
Install
[]
= "0.0.11"
Quick Start
use ;
let value = parse.expect;
assert_eq!;
let reply = object;
assert_eq!;
Object keys come back out in sorted order, which makes serialised output comparable in a test without parsing it again.
Numbers
This implementation stores numbers as f64. JSON itself does not
require that representation. An integer beyond 253 may
lose precision. Do not use this representation for identifiers that
require exact integers beyond that range. A
literal outside f64's range is refused rather than rounded to
infinity.
Development
Everything CI runs: format, clippy, tests, rustdoc, the
#![forbid(unsafe_code)] check, the example, a 95% coverage floor and
an MSRV build. Fuzzing runs in CI on every pull request.
Security
Scorecard scans use a digest-pinned upstream image. Results are retained as CI artifacts and repository posture findings in GitHub code scanning, not published to Scorecard's public service. The badge shows workflow status, not a security score; a successful scan can still report findings.
See SECURITY.md. This crate parses untrusted input by design — both protocols carry it — so it is fuzzed continuously and refuses malformed input rather than guessing at it.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.