RhoeJSON jq Compatibility Roadmap
RhoeJSON ships a jq-inspired filter surface for command-line muscle memory. It does not yet claim full jq compatibility. This roadmap keeps the compatibility story precise while we progressively close the high-impact semantic gaps.
Compatibility Labels
exact-compatible: Behavior is intended to match jq for the documented caseinspired: The spelling or workflow is familiar to jq users, but behaviordeferred: The feature is a planned compatibility candidate but is not partintentionally-unsupported: The feature is outside the current public
and is covered by local tests or the pinned jq subset conformance harness.
is intentionally narrower or RhoeJSON-specific.
of the current release surface.
contract.
Implemented First: Path And Generator Semantics
The current implementation supports jq path arrays and generator-backed mutation for the most important document editing workflows:
path(.field[index])path(.items[].field)pathspaths(predicate)leaf_pathsgetpath(pathArray)setpath(pathArray; value)delpaths(pathArrayList)- generator assignment such as
.records[].score += 1 - generator deletion such as
del(.records[].active)
The pinned subset cases live in Tests/RhoeJSONFilterTests/Fixtures/jq-conformance/subset-cases.json. Maintainers can compare those cases against an installed jq binary with:
bash Scripts/validate-jq-subset-conformance.sh
The offline Swift unit test suite also loads Tests/RhoeJSONFilterTests/Fixtures/jq-conformance/golden-cases.json, a checked-in manifest of exact-compatible jq filters and expected output streams. Those golden fixtures give the public package deterministic regression coverage without requiring jq at test time, while the conformance script re-checks the same checked-in expectations against a local jq oracle when available.
Second Cliff: Variables, Functions, Reduce
The first lexical evaluation slice is implemented:
as $namebindings- destructuring bindings such as
as {name: $name}andas [$a, $b] $namereferences- variable field/index suffixes such as
$record.name reduce stream as $name (initial; update)foreach stream as $name (initial; update)foreach stream as $name (initial; update; extract)try expression catch handler, plustry expressionas an empty-on-error formwhile(condition; update)until(condition; update)recurse,recurse(step), andrecurse(step; condition)walk(filter)error(message)andtry error(...) catch ...haltandhalt_error(status)with CLI-level exit-code propagation- no-argument
def name: filter; ...filters - filter-argument
def name(f; g): ...;functions - recursive user-defined functions
- RhoeJSON-inspired forward references to later
defdefinitions
The jq-oracle harness labels forward references as inspired, not exact-compatible, because jq itself rejects calls to functions that are defined later in the same program. The remaining work in this cliff is narrower non-local control-flow semantics:
labelandbreak
The evaluator environment now carries input value, lexical bindings, function definitions, filter-argument bindings, and a shared input provider for input/inputs. A later diagnostic pass should add source ranges and clearer recursion-depth failure messages.
Then: Regex And String Fidelity
The first regex fidelity slice is implemented:
test(regex)andtest(regex; flags)match(regex)andmatch(regex; flags)capture(regex)andcapture(regex; flags)scan(regex)andscan(regex; flags)sub(regex; replacement)andsub(regex; replacement; flags)gsub(regex; replacement)andgsub(regex; replacement; flags)i,m,s,x, andgregex flags where applicable- named capture interpolation in replacement strings using
\(.name) - jq-style string interpolation with
"\(...)", including embedded filters ltrimstr(...)rtrimstr(...)explodeimplode
that produce multiple output strings or no output via empty
The remaining string fidelity lane should cover:
- replacement expressions that produce streams.
- broader explicit Unicode normalization behavior notes for edge cases beyond
scalar code point conversion.
Then: Format Encoders And Math Utilities
The next utility slice is implemented for high-frequency shell workflows:
@text@json@html@uri@csv@tsv@sh@base64@base64d- jq formatter string semantics where literal text remains literal and
- deterministic math helpers:
abs,floor,ceil,round,sqrt,sin,
\(...) interpolation holes are formatted
cos, tan, log, and exp
The current math contract is intentionally pinned to deterministic finite inputs covered by the subset harness. Broader floating-point edge cases (nan, infinities, platform-specific transcendental rounding) remain outside the 0.1.0 compatibility claim.
Then: jq-Style CLI Flags
The current rhoejson jq command supports these exact-compatible jq-style input/output flags:
-n/--null-input-R/--raw-input-s/--slurp-r/--raw-output--raw-output0-j/--join-output-a/--ascii-output-c/--compact-output-S/--sort-keys--indent n, including jq's-1tab-indentation mode--tab-e/--exit-status-f file/--from-file file
Program-file loading reads one jq-inspired filter source from disk. RhoeJSON now accepts multiple JSON input paths, parses multiple whitespace-separated JSON texts, and exposes jq-style input and inputs over the shared input stream.
It also supports exact jq variable binding flags:
--arg name value--argjson name JSON--rawfile name path--slurpfile name path--args--jsonargs
--args and --jsonargs follow jq's tail-consuming shell grammar: every remaining value token is exposed through $ARGS.positional. As in jq, use the -- end-of-options marker after --args or --jsonargs when a positional value itself begins with -.
The staged public preview also accepts these RhoeJSON convenience forms:
--arg name=value--argjson name=json--rawfile name=path--slurpfile name=path
A fuller jq-compatible shell surface would add:
-Lmodule search paths- color and monochrome-output flags
Later Compatibility Candidates
- Modules:
include,import, namespaces, and metadata. - Streaming:
--stream,tostream,fromstream, andtruncate_stream. - Dates and time:
now,fromdate,todate,strptime, andstrftime. - Non-local control flow:
labelandbreak. - I/O and environment beyond the implemented input stream:
debug,stderr,
env, and $ENV, with explicit determinism and security boundaries. Raw environment exposure is deliberately deferred because public CLI environments often contain tokens and other secrets.
Conformance Strategy
The harness starts with a pinned behavioral subset manifest maintained in this repo. Before claiming broader jq compatibility, we should add a licensing review and pinned import strategy for upstream jq tests, then classify each imported case as exact-compatible, jq-inspired, deferred, or unsupported.