* Native format: the .vectorcraft envelope comes from craft-vectorcraft-format
vectorcraft-format reads and writes the file's envelope through the
craft-vectorcraft-format crate in craft-libs: Head and Image, the version
and size constants, the format and version check, Tail for the data after
the JSON, split_tail and entry, and base64. The constants, is_compressed,
json_part, base64_encode and base64_decode are re-exported from
vectorcraft_format, so callers do not change. load_file reads the members
it uses with Image entries and skips the preview and PDF data. The
document, its migrations, the version 1 writer, gzip writing, sniff and
the limits on decompression stay here.
A preview or pdf member of the wrong shape now reads as missing on its
own, so pdf_content still returns a file's PDF when its preview is
damaged.
A new test saves a document in every version, compressed and pretty,
with a preview, profiles and a PDF, reads it back, saves it again and
compares the bytes; it also reads each uncompressed file as the crate's
File. Another reads the PDF of a file whose preview is damaged.
* Native format: sniff from craft-vectorcraft-format, pinned at #408's head
- craft-vectorcraft-format moves to craft-libs 0fd7e75fe6, the head of
storytold/craft-libs#408.
- `sniff` is the crate's: a file is native when its top-level `format`
member, within the first 256 bytes after decompression, is
`vectorcraft` or `drawcraft`, read with JSON escapes decoded. The word
elsewhere in the head no longer counts. All 192 corpus files and
their resaved copies get the same answer as before.
- Envelope errors other than the format and the version keep the
crate's message instead of reading as a compressed file that unpacks
to too much.
- A test checks that a repeated `generator`, `preview` or `pdf` opens
and any other repeated member is refused, by `load_file` and by the
crate's `Contents` alike.
* Native format: read through the crate's Contents and Entries
Pins craft-vectorcraft-format at 420a27f18f, the current head of
craft-libs#408, and replaces VectorCraft's own copies with the crate's:
- load_file reads the JSON through Contents::read, which also refuses
another format or a newer version. Opened is removed. Messages are
those of main: serde names the struct File, as main's reader did.
- In-memory data after the JSON (uncompressed files, and compressed
files unpacked whole) is read through the crate's Entries.
entries_within keeps its streaming reader for compressed files, whose
data is unpacked entry by entry and is never one slice in memory.
- The streaming reader finds the marker through the crate's marker_at.
- MAX_BLOB is the crate's MAX_ENTRY (1 GiB).
save_to still writes the envelope member by member: it streams the
document into the output and looks for the images it uses as it
writes, and File would need the images before the document. A new test
checks that its output, compact, pretty and compressed, for versions 1
to 4, equals serde_json::to_vec or to_vec_pretty of the crate's File
holding the same members followed by the crate's Tail, so a change to
either side fails.
* Native format: pin craft-vectorcraft-format at craft-libs main
craft-libs#408 merged as 14d5dbb50c; the crate is unchanged from
420a27f18f. A test checks that the crate's sniff takes every layout
VectorCraft has written: the version 1 and 2 files from before the
rename, compact and pretty, and each version save_with writes.
A native save was pretty-printed when the document had at most 2,000
layers and objects and its compact JSON was at most 1 MiB. Pretty
printing puts every coordinate on its own indented line, so traced art
with few paths and many anchors could pass that check and be written at
about five times the size of its compact JSON.
The 1 MiB limit now applies to the pretty-printed document, indented as
the file holds it and in the form the save writes: version 1 anchors,
and placed documents expanded for older versions or Include Linked
Files. Documents whose pretty-printed JSON is over 1 MiB are saved as
compact JSON, even when their compact JSON is under it. The 2,000-object
rule and compressed saves are unchanged. docs/mcp.md describes the rule.
* CI: line tables only for workspace crates, no debug info for dependencies
* CI: one integration-test binary per crate
Each crate's tests/*.rs files become modules of tests/it/main.rs. Files that change
process-wide state (Color Settings, the font database, installed plug-ins, the working
directory), the fuzz sweeps and the test targets the Affinity corpus workflow names stay
their own binaries.
* Docs: name the integration tests' new paths
* CI: xtask test with nextest and doctests, one wasm check, clippy --keep-going
cargo xtask ci runs the tests with cargo nextest (cargo test when it is not installed),
builds them with --lib --bins --tests, runs the doctests as their own step, and checks
the wasm crates in one cargo check --keep-going call.