formats: JsonPointer (RFC 6901) in std/json (step 1 of #81) #435
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Step 1 of #81 (JSON Patch). RFC 6901 JSON Pointer as a typed value in
std/json, with reading and navigation onJsonValue. JSON Patch (RFC 6902) addresses every operation by a pointer, and the reference step of #80 ($refwith a pointer fragment) needs the same type; the epic #80 already says whichever lands first adds it tostd/json. This step is that type, nothing else: no patch operations, no new package.Source
Encode/Decode;std/jsonalready providesJsonValue.Design record point
ROADMAP "Which versions a format supports" (JSON Patch row) and ENCODING.md section 9. Decided by the loop:
std/json(new filestd/json/src/pointer.trb, re-exported withpublic usefromlib.trb, the waystd/tomlsplits its files), not in a package of its own: pointers are defined on JSON documents, #80 already expects it there, and a separate package would force a dependency between two packages for a few dozen lines. Pure TorbScript, nonative.public type JsonPointerholds the list of unescaped reference tokens. Methods, not free functions (#146):JsonPointer.root(),JsonPointer.parse(text: String): Result<JsonPointer, JsonPointerError>(the string form: empty text is the root, otherwise it starts with/;~0is~,~1is/; any other use of~is an error),JsonPointer.parseFragment(text: String)(the URI fragment form of RFC 6901 section 6: percent-decoded as UTF-8, then parsed),text(): String(escaped string form),fragment(): String(percent-encoded form),tokens(): List<String>,child(token: String): JsonPointer,parent(): Option<JsonPointer>,last(): Option<String>;JsonPointerimplementsShow,EqandHashas the neighbouring value types do.JsonValue:get(pointer: JsonPointer): Result<JsonValue, JsonPointerError>(an array token is a decimal index without a leading zero,-names the position after the last item and is an error forget; a missing member or index is an error that names the pointer).JsonPointerErroris a public type withShowandError, naming the pointer text and the reason (syntax, missing member, index out of range, token is not an index, target is not an object or array).-token (the position after the last item) is kept as the token-;JsonValue.getrefuses it, the patch step interprets it foradd.instanceLocation/schemaLocationstrings of #434 stay plain text; #80's reference step may switch to this type, not this step.Acceptance criteria
use JsonPointer, JsonPointerError from "std/json"works;JsonPointer.parse("/foo/0")has the tokens["foo", "0"],text()gives the input back, and the root isJsonPointer.root()withtext()equal to"".{"foo": ["bar", "baz"], "": 0, "a/b": 1, "c%d": 2, "e^f": 3, "g|h": 4, "i\\j": 5, "k\"l": 6, " ": 7, "m~n": 8}) resolve withgetto the values the RFC lists, in the string form and in the URI fragment form (section 6, with%25,%5E,%7C,%5C,%22,%20).parse(p.text())andparseFragment(p.fragment())give an equal pointer;~0/~1are decoded in the order the RFC requires (~01is~1, not/).JsonPointerErrorwith the pointer text and a reason: text that does not start with/(other than empty),~not followed by0or1, invalid percent-escape or invalid UTF-8 in the fragment form, a missing member, an index out of range, an index with a leading zero or a sign,-inget, a token applied to a string, number, boolean or null.std/json/tests/pointer.test.trbcovers the criteria above; every public declaration has its doc comment; touched files passtorb format --check.docs/standard-library/json.mdgets aJsonPointersection (declaration block and atrb checkexample that reads a member of a small document);torb docs check,docs index --check,docs skill --checkanddoc --check --no-run stdare green;skills/regenerated.sh tools/gates.sh a).Touches the seed?
No. A new public type in
std/jsonthat the compiler does not look up by string: the compiler's own use ofstd/json(language server, package upload) is unchanged and only gains declarations, so no two-commit rule applies. One Conventional Commit, plusdocs(std/json): ...if the diff is large:feat(std/json): JsonPointer (RFC 6901) and JsonValue.get.Dependencies
std/json,std/text(UTF-8, percent-decoding helpers if present, otherwise local) andstd/testexist.[loop:torbscript] claim implement by session:loop-torbscript-20261023 until 2026-10-23T21:34Z
[loop:torbscript] implement: JsonPointer (RFC 6901) and JsonValue.get implemented in std/json/src/pointer.trb with the RFC examples tested in string and fragment form, docs and skills regenerated; one commit feat(std/json): JsonPointer (RFC 6901) and JsonValue.get. PR #437, CI success (gates, tier A, bootstrap; run https://git.torb.dev/torbscript/language/actions/runs/1464), next: review. Claim released. Worker usage: about 126k tokens (sonnet).
std/json-patchwith RFC 6902 JSON Patch and the json-patch-tests suite (step 2 of #81) #581