You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Seqs round-trip as seqs, via the tag-27 marker clojure/seq (#29)
* feat: seqs round-trip as seqs, via the tag-27 marker clojure/seq
A Clojure seq used to encode as a plain CBOR array and decode as a vector, so
`'(count ?v)` came back as `[count ?v]`. That is `=` to the original but not
`seq?`, which is how datahike#1145 read a query call as a lookup ref. It also
has a different hasch content address, so a value did not survive its own
round trip.
Every `seq?` value (lists, lazy seqs, conses, ranges, syntax-quoted forms) is
now written as 27(["clojure/seq", <array>]) under :clojure and :archival. The
payload is byte for byte the array the bare encoding writes, so a reader that
does not know the name still finds the elements. It decodes to a seq over the
decoded vector, or () when empty. That is what nippy returns for every seq that
is not a PersistentList: one object on top of the array decode, chunked, O(1)
count. A seq never offered indexed access, so the decoded value does not
either.
:interop, :canonical and :canonical-rfc7049 lock the new `:seqs` option off and
still write a plain array, because those profiles promise agreement with
encoders that have no seqs. `{:seqs false}` turns it off under :clojure.
- Java and ClojureScript writers and readers; canonical scratch writers inherit
the flag. `clojure/seq` is a reserved name, so nav realises it as it does
queues.
- The payload must be an array: null, a set or a map is :boring/bad-tag-content
on both platforms.
- Golden corpus: five new entries, no existing bytes changed.
- The Python and Rust reference readers unwrap the marker to a plain list; the
interop fixture gains a seq.
- Fixtures, the defaults freeze and the nippy widening test move seqs out of
"collapses to a vector".
Readers must be upgraded before writers: an older boring decodes the marker as
an UnknownRecord. Data written before this change still decodes to vectors.
* fuzz-nav: read data-len off the blob's footer, not a re-encode
The nav fuzzer took the value item's length from (encode v) with stringref
on. When nothing clears :index-min, encode-indexed returns the plain encoding
with stringref OFF and no frame, so any value that repeats a string
re-encoded shorter than the blob. The fuzzer's "frame-only" mutations then
landed in the data and were reported as FRAME-CHANGED-DECODE.
The bug was there before #29, but generated seeds almost never repeated a
string. clojure/seq makes every value with two seqs repeat one, and CI went
red. data-len now comes from frame/footer-start, the same way boring.edit
finds the data region.