Skip to content

v0.7.4

Choose a tag to compare

@github-actions github-actions released this 04 Mar 20:43
· 408 commits to main since this release

Added

  • Proptest binary round-trip property test (#39, #42): New tests/properties.rs uses proptest to generate arbitrary structurally valid MARC records and verify that serialization to ISO 2709 and parsing back produces identical results. Covers leader fields, control fields, and data fields with indicators and subfields.
  • Cargo-semver-checks CI workflow (#37, #40): New .github/workflows/semver.yml runs cargo-semver-checks on PRs that touch src/ or Cargo.toml to catch accidental semver-breaking changes.
  • Nightly Miri CI workflow (#38, #41): New .github/workflows/miri.yml runs cargo +nightly miri test --lib on a daily schedule to detect undefined behavior.
  • serialization_never_panics property test (#44, #46): New proptest verifying MarcWriter never panics or errors on any generated record, catching serialization bugs the round-trip test might miss.
  • Deduplicate control field tags in proptest (#43, #45): arb_record() now uses a HashSet to skip duplicate control field tags, ensuring generated records are structurally valid per MARC.

Changed

  • check.sh --quick now skips Python tests (#53, #56): --quick previously skipped the maturin build but still ran Python tests against a stale extension. Now --quick runs rustfmt, clippy, ruff, Rust tests, and doc tests (~10s). Full mode adds doc check, audit, maturin build, and Python tests (~16s).

Fixed

  • Serialization functions now accept wrapped Python Records (#57, #58): record_to_json(), record_to_xml(), record_to_marcjson(), record_to_mods(), record_to_dublin_core(), and record_to_dublin_core_xml() previously rejected Record objects returned by xml_to_record() and other deserialization functions with TypeError: 'Record' object is not an instance of 'Record'. The PyO3 functions expected the raw _mrrc.Record type but received the Python wrapper mrrc.Record. All six functions now use a shared extract_record() helper that accepts both types, matching the pattern already used by record_to_csv().
  • record_to_dublin_core_xml now exported from Python wrapper (#59): The function existed in the Rust extension (_mrrc) but was missing from mrrc/__init__.py imports and __all__, making it inaccessible as mrrc.record_to_dublin_core_xml().
  • Skip rayon tests under Miri (#47, #49): Annotate 4 rayon_parser_pool tests with #[cfg_attr(miri, ignore)] to work around a known stacked borrows violation in crossbeam-epoch 0.9.18 (crossbeam-rs/crossbeam#1181). Tracking re-enablement in #48.
  • Arithmetic overflow panic on malformed leaders (#32): MarcReader, AuthorityReader, and HoldingsReader now return Err(MarcError::InvalidLeader) instead of panicking when record_length or data_base_address in the leader is less than 24. New Leader::validate_for_reading() method performs the check in all three binary readers.
  • Python examples used Python file I/O instead of Rust I/O (#53, #54): All Python examples now pass file path strings to MARCReader/MARCWriter instead of open() file objects, using the Rust I/O backend which releases the GIL. Updated type stub docstring examples to match.

Documentation

  • Agent docs overhaul (#50): New CLAUDE.md with project overview, key files, build/test commands, and architecture reference. Rewritten AGENTS.md replaces inception-era framing, migrates all bd references to br.
  • Docs navigability improvements (#51): Added _mrrc.pyi type stub admonition to Python API reference page. Moved Design and History under Contributing in mkdocs nav.
  • Context7 configuration (#52): New context7.json configuring documentation indexing for source, bindings, Python package, docs, and examples.
  • Migrate bd references to br (#55): Migrated .github/copilot-instructions.md and docs/contributing/release-procedure.md from bd to br commands, with explicit br sync --flush-only + git commit workflow.
  • Updated migration guide (docs/guides/migration-from-pymarc.md) to recommend path-based MARCReader input instead of Python file objects, with comments explaining GIL release and multi-thread parallelism benefits.