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
Repeated control fields silently dropped (#77, #79): Control fields (e.g., multiple 007s) were stored in IndexMap<String, String>, causing later values to overwrite earlier ones. Changed to IndexMap<String, Vec<String>> across all three record types (Record, AuthorityRecord, HoldingsRecord). Updated all 7 serialization formats (ISO 2709, JSON, MARCJSON, MARCXML, CSV, Dublin Core/MODS, BIBFRAME) to emit all values. The pymarc-compatible get_fields() API now correctly returns all repeated control fields, matching pymarc behavior. Thanks to @acdha for reporting.
delete_subfield() did not actually delete (#81, #82): Was returning the value without removing the subfield. Added Rust Field::delete_subfield() method, exposed via PyO3, and updated the Python wrapper to delegate. Now matches pymarc behavior.
recovery_mode validation for authority/holdings readers (#82): Authority and holdings readers now reject invalid recovery_mode values with ValueError instead of silently defaulting to strict.
Changed
Simplified control field API: Removed get_control_field_values() accessor from Record — redundant with direct access to the public control_fields map. get_control_field() remains as a convenience for non-repeatable tags (001, 003, 005, 008).
Reduced code duplication across Python bindings and Rust core (#82):
Extracted _wrap_field() and _wrap_record() helpers in the Python wrapper, replacing 16+ inconsistent wrapping patterns.
Extracted shared reader_helpers.rs for PyO3 reader backends, reducing ~225 lines of copy-paste between authority and holdings readers.
Extracted control_field_char_at() utility for 008 field parsing, replacing 5 duplicated patterns across authority and holdings record types.