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 / .doc / .rtf / .fodt · paragraphs · plain_text · word_count · insert_paragraph / edit_paragraph / edit_table_cell · replace_lossless · reorder_pages · save_docx / save_odt (paragraph props, run formatting, tables) · toc · bibliography · spell_check · mail_merge · accept_revision / reject_revision · fields_by_paragraph · blame | — |
| calc | open .ods / .xlsx / .xls / .fods / .csv · sheets · rows · cells · shared-string + ref resolution · evaluate (recursive-descent formulas: SUM / IF / VLOOKUP …) · set_cell · save_xlsx / save_ods (formulas, merges, named ranges) · sort_sheet · goal_seek · pivot_compute · sparklines · slicers · critical_path · impact_map · cell_impact · rootcause | — |
| impress | open .odp / .pptx / .ppt / .fodp · slides · per-slide text · plain_text · add_slide / delete_slide / reorder_slides · presenter_view · animations · transitions · smartart · 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 · schema · relationships · views · triggers · queries · query / run_query (SELECT over embedded HSQLDB store) · parse_dml | write / save .odb |
| merge | merge3 / merge3_with — 3-way structural merge with per-paragraph provenance · FieldReconciler hook · set_reconciler | calc / impress models |
| crypto · crypto_odf | MS-OFFCRYPTO Agile + Standard and ODF package encryption — is_encrypted / decrypt / encrypt, pure RustCrypto | — |
| dsig | XML-DSig — signer_info · verify_part_digests · verify_signatures · verify_cert_chain · sign_ooxml / sign_odf (hand-rolled Canonical XML) | — |
| ole2 | OLE2 / Compound File Binary container reader + writer — the substrate for the legacy .doc / .xls / .ppt paths · vba_modules extraction | VBA execution |
| minimal PDF 1.4 writer — the "Export to PDF" backend for every app (base-14 Helvetica, no external converter) | — | |
| render | format-neutral render tree that preserves visual formatting — page geometry, runs with their own bold/italic/font/size/colour, per-cell table borders/fills, inline images as base64 for a sandboxed WebView | — |
| meta | document properties across ODF meta.xml, OOXML docProps/core.xml and flat ODF — read, patch, and DocMeta::save write-back | — |
| format | read_part · list_parts · text_blocks · ext (shared ZIP/XML substrate) | — |
| epub | EPUB 3 export — Writer’s File ▸ Export As ▸ EPUB | — |
| workspace | cross-document dependency analysis — a folder of office files read as one dependency graph | — |
| ffi · tauri_plugin | the C ABI for non-Rust hosts, and the Tauri v2 command/event bridge behind the tauri feature | — |
| lib | the Engine, its JSON dispatcher and the module wiring every surface above hangs off | — |
| commands | COMMANDS — the 127-name bus surface, pinned to Engine::invoke's match arms by a drift-guard test | — |
| 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. Feature-level status per LibreOffice / Microsoft Office capability lives in the generated port report.
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 |
| flate2 | raw DEFLATE of ODF entries around AES-256-CBC |
| aes · cbc · sha1 · sha2 · hmac · getrandom | MS-OFFCRYPTO Agile + Standard and ODF package encryption (RustCrypto) |
| x509-cert · rsa | XML-DSig signer-certificate parsing + RSA signature verify/sign |
| regex | the Calc REGEX() worksheet function and wildcard SEARCH |
16 direct dependencies, every one pure Rust: no LibreOffice/UNO runtime, no C++ FFI, no system libraries, no copyleft. Crate types: rlib for native Rust/Tauri hosts; staticlib + cdylib for the C ABI. Two of them (zip + quick-xml) carry the whole reader/writer surface because every office document is a ZIP of XML parts; the rest exist for encrypted packages, digital signatures, and one worksheet function.
Verification
1019 tests ship with the engine (grep -rEn "#\[(tokio::)?test\]" src tests | wc -l): 938 in-module unit tests plus 81 integration tests in tests/engine.rs. The 81 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