A decoded Long/ULong attribute, made JSON-serializable.
Long and ULong columns decode to bigint (feature/attribute.ts), which
JSON.stringify refuses outright. Every emission path therefore goes
through here, and no bigint ever reaches the emitted object.
Three policies, because there is no single right answer:
'lossy-number' (the default) matches what the Rust reader's
serde_json::Number does once the document is written out and read
back by a JSON parser with double semantics -- which is what the
conformance oracle is -- so it is the only policy under which whole-line
comparison against .expected.jsonl is meaningful.
'decimal-string' keeps every digit, at the cost of changing the JSON
type. For a caller that must not lose data.
'error' refuses rather than lose data silently.
The safe-range test is done in bigint arithmetic. Converting first and
comparing afterwards cannot work: Number(2n**53n + 1n) is already
rounded, so it tests equal to the safe boundary it just left.
A decoded
Long/ULongattribute, made JSON-serializable.LongandULongcolumns decode tobigint(feature/attribute.ts), whichJSON.stringifyrefuses outright. Every emission path therefore goes through here, and nobigintever reaches the emitted object.Three policies, because there is no single right answer:
'lossy-number'(the default) matches what the Rust reader'sserde_json::Numberdoes once the document is written out and read back by a JSON parser with double semantics -- which is what the conformance oracle is -- so it is the only policy under which whole-line comparison against.expected.jsonlis meaningful.'decimal-string'keeps every digit, at the cost of changing the JSON type. For a caller that must not lose data.'error'refuses rather than lose data silently.The safe-range test is done in
bigintarithmetic. Converting first and comparing afterwards cannot work:Number(2n**53n + 1n)is already rounded, so it tests equal to the safe boundary it just left.