Repository navigation
Add Excel .xlsx / ODS spreadsheet parser - #44
Conversation
New XlsxParser in ax-normalize. The first worksheet of a workbook (.xlsx/.xls/.xlsb/.ods) becomes a RecordSet: the first row is the header (column names), each subsequent row a record, and every cell maps to the closed Value set — so all detectors apply with no special-casing. A date/time cell keeps its Excel serial number (numeric, deterministic); blank and error cells are Null. Reading is delegated to calamine (pure Rust, all four formats). Detected by the ZIP magic (PK\x03\x04) plus an xl/ part (xlsx/xlsb) or the OpenDocument- spreadsheet mimetype (ods), so a docx/jar/plain zip is not claimed; the OLE2 xls is covered by extension. Confidence MAGIC; extensions xlsx/xls/xlsb/ods. Behind the default-on xlsx feature (binary format), so the text-only build stays lean. Roundtrip test writes a tiny .xlsx in-memory with rust_xlsxwriter (dev-dep, no committed binary); data_to_value and header_name are unit-tested across all cell kinds; non-workbook input is a clean Parse error. Mutation gate: 0 surviving mutants on the new file. Closes #21 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis PR adds optional spreadsheet parsing to ax-normalize using the calamine crate. It introduces a new XlsxParser that detects and parses Excel/ODS files by reading the first worksheet into columns, with header inference and cell-to-Value conversion rules including NaN nullification and date serial preservation. ChangesXLSX Parser Feature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Implements the Excel / OpenDocument plugin — issue #21.
What
The first worksheet of a workbook (
.xlsx/.xls/.xlsb/.ods) becomes aRecordSet: the first row is the header (column names), each subsequent row a
record, and every cell maps to the closed
Valueset — so all detectors applywith no special-casing. A date/time cell keeps its Excel serial number
(numeric, deterministic); blank and error cells are
Null(honest absence).Reading is delegated to
calamine(pure Rust, reads all four formats).Routing
PK\x03\x04) plus anxl/part (xlsx/xlsb) or theOpenDocument-spreadsheet mimetype (ods) — so a
.docx/.jar/ plain zip isnot claimed. The OLE2-based
.xlsis covered by extension.MAGIC; extensions.xlsx/.xls/.xlsb/.ods.Feature gating
Behind the default-on
xlsxfeature (binary format), so the text-only--no-default-featuresbuild stays lean. Both builds verified.Testing
The roundtrip test writes a tiny
.xlsxin-memory withrust_xlsxwriter(dev-dependency — no committed binary fixture) and parses it back;
data_to_valueandheader_nameare unit-tested across every cell kind(int/float/NaN/string/bool/date/empty/error); non-workbook input is a clean
AxError::Parse.Gates
fmt/clippy -D warnings/ full workspace tests green (default and--no-default-features).xlsx.rs.Closes #21
🤖 Generated with Claude Code
Summary by CodeRabbit