ocaml-json: Cursor zipper over Value.t with JSON Pointer (RFC 6901)
Mirror the [ocaml-yaml] addition: a [Json.Cursor] module that zips
a {!Value.t}, exposes [up] / [down_field] / [down_index] /
[replace] / [to_value], bridges to [Loc.Context.t] via
[to_context] / [of_context], and renders / parses
{{:https://www.rfc-editor.org/rfc/rfc6901}JSON Pointer (RFC 6901)}
addresses through [pointer] / [of_pointer].
The implementation follows the YAML side line-for-line, retargeted at
JSON's data model: frames are [Array] (focus inside an array, plus
the index of the focused slot) and [Object] (focus inside an object,
plus the [Value.name] node of the matched member). Object members
that survive an [up] reuse the original [Value.name] node, so the
member's source meta is preserved across edits.
Pointer rules per RFC 6901:
- [""] is the root; non-empty pointers must start with [/].
- Tokens are escape-decoded as [~1] -> [/] then [~0] -> [~] (§4).
- Array indices follow the §5 grammar
[array-index = %x30 / ( %x31-39 *DIGIT )]: leading-zero indices
are rejected. The [-] index from RFC 6902 (Patch's "one past the
last element") is not accepted here — Pointer references existing
values only.
Tests: 9 cases — focus/root, down_field/down_index, replace+zip
round-trip, [pointer] root, pointer round-trip on
[/users] / [/users/0] / [/users/0/name], escape decode of
[/tilde~0slash~1], leading-zero rejection, and to_context shape.