rust_uno/doc/Rust_UNO_Developer_Guide.md |  206 +++++++++++++++++++++++++++++++
 rust_uno/doc/Rust_UNO_User_Guide.md      |  202 ++++++++++++++++++++++++++++++
 2 files changed, 408 insertions(+)

New commits:
commit a7ef6f04e92d7b89d6fa10b1e4766b444312c0a0
Author:     Mohamed Ali <[email protected]>
AuthorDate: Mon Jan 26 07:06:01 2026 +0200
Commit:     Stephan Bergmann <[email protected]>
CommitDate: Tue Jan 27 08:53:19 2026 +0100

    Rust Bindings: Add initial documentation for Rust UNO bindings
    
    Change-Id: Ibb2978ebf1bbca8afddd13bdf8fba5e070c9037f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198115
    Reviewed-by: Stephan Bergmann <[email protected]>
    Tested-by: Jenkins

diff --git a/rust_uno/doc/Rust_UNO_Developer_Guide.md 
b/rust_uno/doc/Rust_UNO_Developer_Guide.md
new file mode 100644
index 000000000000..114228248461
--- /dev/null
+++ b/rust_uno/doc/Rust_UNO_Developer_Guide.md
@@ -0,0 +1,206 @@
+# Rust UNO Developer Guide
+
+<!--toc:start-->
+- [Rust UNO Developer Guide](#rust-uno-developer-guide)
+  - [Table of Contents](#table-of-contents)
+  - [Project Overview](#project-overview)
+  - [Codebase Structure](#codebase-structure)
+    - [Code Generator (`codemaker`)](#code-generator-codemaker)
+    - [Runtime Library (`rust_uno`)](#runtime-library-rustuno)
+  - [The Rustmaker Generator](#the-rustmaker-generator)
+    - [Generation Flow](#generation-flow)
+    - [Key Implementation Details](#key-implementation-details)
+  - [Development Workflow](#development-workflow)
+    - [Prerequisites](#prerequisites)
+    - [Rebuilding Bindings](#rebuilding-bindings)
+  - [Testing Strategy](#testing-strategy)
+    - [Integration Tests](#integration-tests)
+    - [Unit Tests](#unit-tests)
+    - [Future Work: Embindtest](#future-work-embindtest)
+<!--toc:end-->
+
+This guide is intended for contributors working on the **Rust UNO bindings** 
implementation itself. If you are a user looking to *use* the bindings, please 
see the [User Guide](Rust_UNO_User_Guide.md).
+
+## Table of Contents
+
+1. [Project Overview](#project-overview)
+2. [Codebase Structure](#codebase-structure)
+3. [The Rustmaker Generator](#the-rustmaker-generator)
+4. [Development Workflow](#development-workflow)
+5. [Testing Strategy](#testing-strategy)
+
+---
+
+## Project Overview
+
+The Rust UNO project enables LibreOffice to be scripted and extended using 
Rust. It works by inspecting the UNO IDL (Interface Definition Language) types 
and generating:
+
+1. **Rust Wrappers**: Safe, idiomatic Rust structs.
+2. **C++ Bridges**: `extern "C"` functions that handle the raw UNO C++ API.
+
+The system is fully integrated into the LibreOffice build system via 
`autogen.sh` and `make`.
+
+---
+
+## Codebase Structure
+
+The project is split across the core LibreOffice codebase:
+
+### Code Generator (`codemaker`)
+
+Located in `codemaker/source/rustmaker/`. This tool reads the binary type 
library (RDB files) and outputs source code.
+
+| File | Purpose |
+|------|---------|
+| `rustproduce.cxx` | Generates Rust source files (structs, enums, 
interfaces). |
+| `cpproduce.cxx` | Generates the C++ side of the bridge. |
+| `unoproduce.cxx` | Coordinator that drives the generation process. |
+| `rustfile.cxx` | Helper for writing Rust source files (indentation, 
imports). |
+
+### Runtime Library (`rust_uno`)
+
+Located in `rust_uno/`. This is the crate that users depend on.
+
+- `src/lib.rs`: Crate root, exports `generated` modules.
+- `src/generated/`: Destination for generated Rust code.
+- `src/core/`: Handwritten core utilities (`OUString` wrapper, primitive 
types).
+
+---
+
+## The Rustmaker Generator
+
+The heart of the project is the `rustmaker` binary. It runs during the build 
process to produce the bindings.
+
+### Generation Flow
+
+```mermaid
+graph LR
+    IDL["UNO IDL Files"] -->|idlc| RDB["Binary RDB"]
+    RDB -->|read by| RustMaker["rustmaker (codemaker)"]
+    RustMaker -->|writes| RustFiles["Rust Wrappers (.rs)"]
+    RustMaker -->|writes| CppFiles["C++ Bridge (.cxx)"]
+
+    RustFiles -->|compiled by| Rustc["rustc"]
+    CppFiles -->|compiled by| Gxx["g++"]
+
+    Rustc -->|links| SharedLib["lib_rust_uno.so"]
+    Gxx -->|links| SharedLib
+```
+
+### Key Implementation Details
+
+- **Typed Parameters**: Methods are generated with native types (e.g. `i32`, 
`bool`) where possible.
+- **Opaque Pointers**: All UNO objects are held as `*mut c_void` in Rust, 
pointing to a `Ref<Interface>` in C++.
+- **Memory Management**: The `Drop` trait implementation calls the C++ 
destructor, which releases the UNO reference.
+
+---
+
+## Development Workflow
+
+### Prerequisites
+
+Ensure you have a full LibreOffice build environment and have run 
`./autogen.sh --enable-rust-uno`.
+
+### Rebuilding Bindings
+
+When you modify `codemaker`, you need to regenerate the bindings:
+
+```bash
+# Rebuild the generator
+make codemaker
+
+# Regenerate the source files
+make rust_uno
+
+# Rebuild the final library
+make
+```
+
+> [!TIP]
+> If you see bizarre errors after changing `rustmaker`, try `make 
rust_uno.clean` first to force a fresh generation.
+
+---
+
+## Testing Strategy
+
+Testing is integrated into the LibreOffice startup sequence for basic sanity 
checks.
+
+### Integration Tests
+
+The entry point `run_rust_uno_test` in `rust_uno/src/lib.rs` is called by 
`soffice` on startup.
+It runs scenarios defined in `rust_uno/src/examples/`.
+
+To run the tests:
+
+```bash
+./instdir/program/soffice --norestore
+```
+
+Watch the console output for `=== Rust UNO Bridge Test ===`.
+
+### Unit Tests
+
+Pure Rust unit tests (for `OUString` logic, etc.) can be run via Cargo:
+
+```bash
+cd rust_uno
+cargo test
+```
+
+### Future Work: Embindtest
+
+We plan to integrate with `embindtest`, the comprehensive UNO test suite. This 
is a high-priority task to ensure full coverage of generated types.
+
+## Roadmap and Missing Features
+
+This section details the current implementation status and future development 
tasks, ordered by architectural dependency and impact.
+
+### Implementation Status
+
+The following table summarizes the generation status of UNO types in 
`codemaker`.
+
+| UNO Type | Status | Generator Function | Notes |
+|----------|--------|-------------------|-------|
+| **Module** | Implemented | `produceModule()` | Generates directory structure 
and `mod.rs` files. |
+| **Enum** | Implemented | `produceEnum()` | Full support including validation 
and bridge functions. |
+| **Struct** | Implemented | `produceStruct()` | Generates PlainStructs with 
getters, setters, and constructors. |
+| **Interface** | Implemented | `produceInterface()` | Generates traits, 
wrappers, and reference-counting logic. |
+| **Service** | Partial | `produceService()` | Supports single-interface 
services; accumulation-based services are deprecated. |
+| **Sequence** | Partial | `rustproduce.cxx` | Currently handled as `void*` in 
FFI; lacks safe Rust wrappers. |
+| **ConstantGroup** | Not Implemented | `produceConstantGroup()` | Function 
exists but body contains only a log message; content is skipped. |
+| **Exception** | Not Implemented | `produceException()` | Function exists but 
body contains only a log message; code generation is missing. |
+
+### Development Tasks
+
+The following tasks are ordered by their foundational importance to the 
binding quality.
+
+#### 1. ConstantGroup Generation
+**Goal**: Generate Rust constants for UNO ConstantGroups (e.g., 
`com.sun.star.awt.FontWeight`).
+**Files**: `codemaker/source/rustmaker/rustproduce.cxx`, `cpproduce.cxx`
+**Details**: Currently, `produceConstantGroup` prints a skipping message. This 
needs to look up the constants in the IDL entity and generate a Rust `module` 
with `const` items.
+
+#### 2. Exception Mapping
+**Goal**: Integrate UNO exceptions with Rust's `Result` type.
+**Files**: `codemaker/source/rustmaker/`
+**Details**:
+*   Generate structs for UNO Exception types (`produceException`).
+*   Update method signatures to return `Result<T, UnoError>` instead of 
`Option<T>`.
+*   The C++ bridge currently catches exceptions but does not fully propagate 
type information to Rust.
+
+#### 3. Typedef Resolution
+**Goal**: Resolve UNO typedefs to their concrete Rust types.
+**Files**: `codemaker/source/rustmaker/unoproduce.cxx`
+**Details**: `produceTypedef` currently prints a log message. It should 
resolve the aliased type and generate a `type Alias = ConcreteType;` definition 
in Rust.
+
+#### 4. Singleton Generation
+**Goal**: Generate accessors for UNO singletons.
+**Files**: `codemaker/source/rustmaker/rustproduce.cxx`
+**Details**: `produceSingleton` is currently a placeholder. It should generate 
helper methods to retrieve the singleton instance (typically via component 
context), avoiding manual `createInstance` calls.
+
+#### 5. Type-Safe Sequences
+**Goal**: Replace `void*` usage for Sequences with a proper `Sequence<T>` 
wrapper.
+**Files**: `codemaker/source/rustmaker/rustproduce.cxx`, `rust_uno/src/core/`
+**Details**: Implement a `Sequence` struct that manages the memory layout 
compatible with UNO sequences and implements `Iterator`.
+
+---
+
diff --git a/rust_uno/doc/Rust_UNO_User_Guide.md 
b/rust_uno/doc/Rust_UNO_User_Guide.md
new file mode 100644
index 000000000000..afea64e6cc1a
--- /dev/null
+++ b/rust_uno/doc/Rust_UNO_User_Guide.md
@@ -0,0 +1,202 @@
+# Rust UNO User Guide
+
+<!--toc:start-->
+- [Rust UNO User Guide](#rust-uno-user-guide)
+  - [Table of Contents](#table-of-contents)
+  - [Introduction](#introduction)
+  - [Prerequisites & Setup](#prerequisites-setup)
+    - [Requirements](#requirements)
+    - [Enabling Rust Support](#enabling-rust-support)
+    - [Building](#building)
+  - [Architecture Overview](#architecture-overview)
+  - [Quick Start](#quick-start)
+    - [1. Dependencies](#1-dependencies)
+    - [2. Loading a Document](#2-loading-a-document)
+  - [Core Concepts](#core-concepts)
+    - [Interfaces](#interfaces)
+    - [Strings](#strings)
+    - [Memory Management](#memory-management)
+    - [Troubleshooting](#troubleshooting)
+<!--toc:end-->
+
+Welcome to the **Rust UNO Bindings** user guide. This document provides 
comprehensive instructions for using Rust to interact with LibreOffice via the 
UNO (Universal Network Objects) API.
+
+## Table of Contents
+
+1. [Introduction](#introduction)
+2. [Prerequisites & Setup](#prerequisites--setup)
+3. [Architecture Overview](#architecture-overview)
+4. [Quick Start](#quick-start)
+5. [Core Concepts](#core-concepts)
+6. [Troubleshooting](#troubleshooting)
+
+---
+
+## Introduction
+
+The Rust UNO bindings provide a safe, high-performance interface to automate 
LibreOffice. Unlike Python or Java bindings which rely heavily on runtime 
reflection, Rust UNO uses **compile-time generated wrappers** ensuring:
+
+- **Type Safety**: Errors are caught at compile time.
+- **Performance**: Zero-cost abstractions over the C++ bridge.
+- **Memory Safety**: Automatic resource management via RAII (Drop trait).
+- **Typed Parameters**: Methods take native Rust types (`bool`, `i32`) instead 
of unsafe `void*` pointers.
+
+---
+
+## Prerequisites & Setup
+
+To use Rust UNO, you must build it as part of LibreOffice.
+
+### Requirements
+
+- **Rust**: Stable toolchain (install via `rustup`).
+- **LibreOffice Build Deps**: Standard development environment for LibreOffice.
+- **Disk Space**: Sufficient space for a full LibreOffice build.
+
+### Enabling Rust Support
+
+Add the following to your `autogen.input` file or pass it to `autogen.sh`:
+
+```bash
+--enable-rust-uno
+```
+
+### Building
+
+Run the following commands to generate bindings and build LibreOffice:
+
+```bash
+./autogen.sh
+make codemaker # Builds the IDL compiler
+make rust_uno  # Generates Rust/C++ bridge code
+make           # Final build
+```
+
+> [!NOTE]
+> The generated Rust unit tests run automatically during the build process to 
verify the bridge.
+
+---
+
+## Architecture Overview
+
+The bindings utilize a 3-layer architecture to safely bridge safe Rust with 
C++ UNO.
+
+```mermaid
+graph TD
+    UserCode["Your Rust Code"] -->|Calls| RustWrapper["Rust Wrappers"]
+    RustWrapper -->|FFI| CppBridge["C++ Bridge (extern C)"]
+    CppBridge -->|Calls| NativeUNO["Native LibreOffice C++ API"]
+
+    subgraph "Layer 1: Safe Rust"
+    RustWrapper
+    end
+
+    subgraph "Layer 2: FFI Bridge"
+    CppBridge
+    end
+
+    subgraph "Layer 3: Core"
+    NativeUNO
+    end
+```
+
+1. **Rust Wrappers** (`rust_uno/src/generated/`): Safe structs holding opaque 
pointers. Methods are fully typed.
+2. **C++ Bridge** (`workdir/CustomTarget/rust_uno/rustmaker/cpp/`): Handles 
exception catching and reference counting.
+3. **Native UNO**: The actual LibreOffice implementation.
+
+---
+
+## Quick Start
+
+### 1. Dependencies
+
+Ensure your `Cargo.toml` includes the dependencies. Since `rust_uno` is 
currently built in-tree, you point to it using a path dependency:
+
+```toml
+[dependencies]
+rust_uno = { path = "rust_uno" }
+```
+
+### 2. Loading a Document
+
+Here is a complete example of bootstrapping UNO and loading a Writer document. 
This demonstrates the **Typed Parameter API**.
+
+```rust
+use rust_uno::generated::rustmaker::com::sun::star::frame::{Desktop, 
XComponentLoader};
+use rust_uno::generated::rustmaker::com::sun::star::text::XTextDocument;
+use rust_uno::core::{OUString, 
uno_wrapper::defaultBootstrap_InitialComponentContext};
+use std::ptr;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+    // 1. Bootstrap the component context
+    let context = defaultBootstrap_InitialComponentContext()?;
+
+    // 2. Create the Desktop service
+    // Wrappers take raw pointers for low-level compatibility, or other 
wrappers
+    let desktop = Desktop::create(context.as_ptr())
+        .ok_or("Failed to create Desktop service")?;
+
+    // 3. Query the XComponentLoader interface
+    // Interface conversion is explicit and safe
+    let loader = XComponentLoader::from_ptr(desktop.as_ptr())
+        .ok_or("Desktop does not support XComponentLoader")?;
+
+    // 4. Load a blank Writer document
+    let url = OUString::from("private:factory/swriter");
+    let target = OUString::from("_blank");
+
+    // Note: Typed parameters! No casting to void* needed.
+    let component = loader.loadComponentFromURL(
+        url,                // Passed by value (moved) or reference depending 
on signature
+        target,
+        0,                  // i32
+        ptr::null_mut()     // Any/Sequence arguments
+    ).ok_or("Failed to load component")?;
+
+    // 5. Use the document
+    if !component.as_ptr().is_null() {
+         let text_doc = XTextDocument::from_ptr(component.as_ptr())
+             .ok_or("Loaded component is not a TextDocument")?;
+
+         if let Some(text) = text_doc.getText() {
+             println!("Document loaded successfully!");
+             // text.setString(OUString::from("Hello Rust!"));
+         }
+    }
+
+    Ok(())
+}
+```
+
+---
+
+## Core Concepts
+
+### Interfaces
+
+UNO interfaces map directly to Rust structs.
+
+- **C++**: `Reference<XInterface>`
+- **Rust**: `pub struct XInterface { ptr: *mut c_void }`
+
+### Strings
+
+LibreOffice uses `OUString` (UTF-16). The bindings provide efficient 
conversion:
+
+- `OUString::from("Hello")`: Rust string slice -> OUString
+- `ou_string.to_string()`: OUString -> Rust String
+
+### Memory Management
+
+Rust's `Drop` trait automatically calls `acquire` and `release` on the 
underlying UNO objects via the C++ bridge. You do not need to manually manage 
reference counts.
+
+### Troubleshooting
+
+| Issue | Cause | Solution |
+|-------|-------|----------|
+| `make rust_uno` fails | Codemaker out of date | Run `make rust_uno.clean && 
make codemaker && make rust_uno` |
+| Runtime panic "Symbol not found" | LD_LIBRARY_PATH missing | Run your binary 
via `instdir/program/soffice --norestore` environment or set paths manually. |
+| `Option::None` from query | Interface not supported | Check API docs to 
ensure the object supports the interface you are querying. |
+
+> [!TIP]
+> Always check `instdir/program/soffice` execution logs. The rust bridge 
prints initialization status to stdout/stderr with `SAL_WARN` channels if 
enabled.

Reply via email to