ZOFFICE-CORE // EMBEDDABLE OFFICE ENGINE

// pure-Rust parse + edit for documents · spreadsheets · presentations — the core behind zoffice, embeddable in any host GUI

zoffice-core is the embeddable engine behind zoffice, the cyberpunk desktop office suite. It owns the document models — Writer, Calc, Impress, Draw, Math, Base — and the open / read / save operations for ODF and OOXML packages, with no GUI and no platform dependencies, so the desktop app and every embed (traderview and the other MenkeTechnologies apps) share the exact same code. Every office format is an OPC/ODF ZIP of XML parts, so the whole reader surface rides two pure-Rust crates (zip, quick-xml): no LibreOffice/UNO runtime, no C++ FFI, no AGPL — clean to ship inside a paid, closed-source host.

The document, spreadsheet, presentation, drawing, and formula apps parse real ODF/OOXML packages and write them back today: editing, saving (save_docx / save_odt / save_xlsx / save_ods / save_pptx / save_odp / save_odg), and a real recursive-descent formula evaluator (SUM, IF, VLOOKUP, …) all exist, and Base reads its .odb catalog and runs SELECT queries over the embedded store. Encrypted packages (MS-OFFCRYPTO and ODF) and XML digital signatures are read, written, verified and signed in pure Rust. The port report derives per-capability status from the actual source symbols: 236 of 245 mapped Office/LibreOffice capabilities implemented, 0 stubbed, 9 planned — Power Query, cube functions, Base forms rendering, external DB connectors, VBA macro execution, IRM / rights management, the host-GUI formula editor, the Tauri command layer, and digital-signature verification. The last two lag the source rather than the code: the Tauri layer is wired in the zoffice app, and src/dsig.rs verifies and signs XML-DSig today — neither is cited by a symbol in scripts/feature_map.json, so the generator still counts them planned. Writing an .odb database back out is the remaining gap the module map calls out. See the engineering report for the module map and the port report for the feature-level table.

Embeddable

Links as an rlib into Rust/Tauri hosts and over a C ABI (staticlib/cdylib) elsewhere. One FFI call: a command name plus a JSON argument string returns a JSON string.

Pure Rust

Two crates for the package layer (zip, quick-xml) plus serde/thiserror. Durable, vendorable, no native toolchain, no copyleft, no UNO runtime.

Honest Coverage

A capability counts as done only when a real engine symbol exists; stubs return a typed error rather than panicking or silently succeeding. Status is derived from source, not asserted.

The six apps

appLibreOffice / MicrosoftODF readsOOXML reads
writerWriter / Word.odt.docx
calcCalc / Excel.ods.xlsx
impressImpress / PowerPoint.odp.pptx
drawDraw / —.odg
mathMath / —.odf
baseBase / Access.odb

Quick start (Rust host)

use zoffice_core::{Document, Engine};
use serde_json::json;

// Typed module API.
let doc = Document::open('report.docx')?;
println!('{} paragraphs, {} words', doc.paragraph_count(), doc.word_count());
println!('{}', doc.plain_text());

// Or the JSON dispatcher the FFI and Tauri hosts call.
let engine = Engine::new();
let out = engine.invoke('writer.text', &json!({ 'path': 'report.docx' }))?;

From a C host

/* one call across the C ABI: command + JSON args -> JSON string */
char *out = zoffice_invoke('calc.cells', '{\"path\":\"budget.xlsx\"}');
/* ... use out ... */
zoffice_string_free(out);

The C ABI is exposed in the staticlib/cdylib artifacts and absent from the Rust rlib public API. Any failure comes back as the engine's {"error":{"tag":...,"message":...}} envelope, so a C caller never inspects a separate status code.

Where it goes next

See the engineering report for the module map, dependency footprint, and test status, and the project repos: zoffice-core and the umbrella MenkeTechnologiesMeta.