Status from source, stated honestly. zoffice-core both reads and writes ODF and OOXML packages today: editing, saving, a real recursive-descent Calc formula evaluator, presentation authoring (add_slide), and the Base database backend (catalog reads plus SELECT queries over the embedded store) all have real bodies — there are no remaining Error::NotImplemented stubs in the module code. The module map below marks exactly what is implemented now versus planned. Status is derived from the actual fn symbols in src/ — a capability is done only once its body exists, and the test suite pins that out-of-range and unknown-command paths return a typed error rather than panicking or silently succeeding.
Module map
| module | implemented now | planned / stubbed |
|---|---|---|
| writer | open .odt / .docx · paragraphs · plain_text · word_count · insert_paragraph / edit_paragraph · save_docx / save_odt · style_definitions / style_count | — |
| calc | open .ods / .xlsx · sheets · rows · cells · shared-string + ref resolution · evaluate (recursive-descent formulas: SUM / IF / VLOOKUP …) · set_cell · save_xlsx / save_ods · sort_sheet | — |
| impress | open .odp / .pptx · slides · per-slide text · plain_text · add_slide · save_pptx / save_odp | — |
| draw | open .odg · pages · shapes · shape_count · to_svg / export_svg · save / save_odg | — |
| math | open .odf · MathML + StarMath annotation extraction · to_starmath · layout | — |
| base | open .odb · tables · queries · query / run_query (SELECT over embedded HSQLDB store) | write / save .odb |
| format | read_part · list_parts · text_blocks · ext (shared ZIP/XML substrate) | — |
| error | typed errors · JSON envelope · missing_arg helper | — |
The lib root adds the Engine JSON dispatcher (info, open auto-detect, and the per-app <app>.open / .text / calc.cells commands) plus App / app_for extension routing; ffi exposes the C ABI (zoffice_invoke / zoffice_string_free) in the staticlib/cdylib artifacts.
Dependency footprint
| crate | role |
|---|---|
| zip | OPC/ODF package container (deflate, no system deps) |
| quick-xml | streaming XML reader over the package parts |
| serde · serde_json | model serialization + the JSON command boundary |
| thiserror | typed error enum |
| dirs | platform paths |
No LibreOffice/UNO runtime, no C++ FFI, no copyleft. Crate types: rlib for native Rust/Tauri hosts; staticlib + cdylib for the C ABI. Two crates carry the whole reader/writer surface because every office document is a ZIP of XML parts.
Verification
46 integration tests build minimal valid office packages in memory (ODF or OOXML — both are just ZIP-of-XML), write each to a temp file, and drive the public API: docx and odt paragraph extraction and authoring round-trips (edit_paragraph → save_docx / save_odt), xlsx shared-string + cell-reference resolution and a set_cell → save_xlsx round-trip, ods cell parsing with computed refs, Calc formula evaluation (arithmetic, the function library, VLOOKUP, text/compare, sort_sheet), pptx multi-slide text plus add_slide and save_pptx round-trips, odg page/shape counting and a save_odg round-trip, math MathML → StarMath, Base catalog reads and queries, the Engine JSON dispatcher plus its info descriptor, and a guard that out-of-range targets and unknown commands return a typed error rather than panicking. No external fixtures; runs identically in a headless Linux CI.
cargo test cargo build # rlib + staticlib + cdylib