vendor:json depends on vendor:edn for nothing, and borrowing a shape walk across that line would be a dependency for the sake of a resemblance. What carries over is the shape of the answer — one walk giving a type, the declarations that type needs and the expression that reads one; a refusal carried in a field rather than raised; a typed one-line constructor per collection; and a compile-error wrapped in a defn nothing calls. What is genuinely different is four things. Strings go through string-of and never through .text: .text is the raw interior with escapes undecoded, so a field read off it would hold a backslash and an n where the file meant a newline — which is the first two lines of the acceptance output and the reason they are two. Commas and colons are tokens rather than whitespace. An object's keys are strings, so a key has to be refused when it is not a name a program could write, and refused again when it carries an escape: the generated reader compares against the bytes as written, which costs no allocation per key and is only the same question when the name is written plainly. And there are no sets, so there is no map-key path and no fixed array — every collection is a (Vec T) and defjson is the smaller of the two by half. JSON has no integer type; the tokenizer draws the line at whether a number has a fraction or an exponent, which is the only line there is, so 1 derives i64 and 1.0 derives f64. That is the file's own distinction and the honest one to take. @x86 matches on it and @sanitize is clean.
13 lines
192 B
JSON
13 lines
192 B
JSON
{
|
|
"name": "tileset\nrunner",
|
|
"port": 8080,
|
|
"scale": 1.5,
|
|
"debug": true,
|
|
"layers": [3, 1, 4, 1, 5],
|
|
"window": {
|
|
"w": 1280,
|
|
"h": 720,
|
|
"origin": { "x": -2, "y": 0 }
|
|
}
|
|
}
|