Conversation
Resolve the parse/emit string-representation split (mach-std#340) with a decode-on-demand accessor: the parser keeps storing raw wire bytes (zero-copy), and value_string_decode unescapes them into logical bytes at the point of consumption -- the inverse of the emit escaper. Handles " \ \/ \b\f\n\r\t and \uXXXX including surrogate-pair astral code points decoded to UTF-8, erroring on malformed escapes. Documents the raw-vs-decoded contract on the storage field and both accessors.
Escape matrix (short escapes, \uXXXX BMP incl. uppercase hex, surrogate-pair astral -> UTF-8, verbatim UTF-8 pass-through), malformed-escape rejection (bad escape, truncated/non-hex \u, unpaired/lone/bad surrogate, trailing backslash), the emit size-then-fill buffer protocol, and the reframed round-trip decode(parse(emit(make_string(L)))) == L.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #340.
Problem
std.data.jsonstored two incompatible meanings in one field: parse yields theraw on-wire bytes between the quotes (escapes intact, zero-copy), while emit
treats
str_valas logical bytes and re-escapes. Aparse -> emitpipelinedouble-escaped every wire escape.
Decision
Per the issue (2026-07-03, delegated): decode-on-demand accessor. Zero-copy
raw parse stays; a decoding accessor gives correct string semantics at the
consumption point without making every parse pay decode cost.
Change
value_string_decode(v, buf, len) -> Result[usize, str]: resolves the raw wireescapes of a string value into logical bytes in a caller buffer — the inverse
of the emit escaper. Handles
\" \\ \/ \b \f \n \r \tand\uXXXX(a high+lowsurrogate pair combines into one astral code point, encoded to UTF-8 via the
validated
std.text.utf8encoder). Errors on malformed escapes (unknownescape,
\uwithout four hex digits, ill-formed surrogate pair). Uses the samecounting-
BufWritersize-then-fill protocol asemit.str_val,value_string, the newaccessor, and the file header.
Emit semantics are unchanged — this PR adds the decode path only.
Tests
Escape matrix (short escapes,
\uXXXXBMP, surrogate-pair astral, verbatimUTF-8 pass-through), malformed-escape errors, buffer-sizing protocol, and the
reframed round-trip
decode(parse(emit(make_string(L)))) == L.