zhixi-document-runtime/docs/uniffi-udl-spec.md
wangdl fcb01f29c3
Some checks failed
CI/CD Pipeline / Lint (push) Has been cancelled
CI/CD Pipeline / Test (push) Has been cancelled
CI/CD Pipeline / Build (push) Has been cancelled
CI/CD Pipeline / Release (macos-15, aarch64-apple-ios, aarch64-apple-ios) (push) Has been cancelled
CI/CD Pipeline / Release (macos-15, aarch64-apple-ios-sim, aarch64-apple-ios-sim) (push) Has been cancelled
CI/CD Pipeline / Package xcframework (push) Has been cancelled
fix: UniFFI version 0.28→0.31 in docs
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 15:06:06 +08:00

274 lines
6.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UniFFI UDL 编写规范 + 代码生成流程
## 1. 概述
UniFFIUniversal Foreign Function Interface是 Mozilla 开发的跨语言绑定生成工具。本项目使用 UniFFI 0.31 从 Rust 生成 Swift 绑定。
UDLUniFFI Definition Language文件定义跨语言接口。
---
## 2. UDL 语法规范
### 2.1 命名空间
```webidl
namespace zx_document {
// 导出函数
};
```
命名空间名即 Swift 模块名(`zx_document`)。
### 2.2 函数声明
```webidl
// 基础函数
MaterialType detect_material_type([ByRef] string file_path);
// 可抛异常
[Throws=DocumentError]
DocumentInfo build_document_info([ByRef] string file_path, string material_id, string title);
// 无返回值
void push_reading_event(ReadingEvent event);
```
#### 参数修饰符
| 修饰符 | 适用类型 | 说明 |
|--------|----------|------|
| `[ByRef]` | `string` | 传递引用而非所有权转移(性能优化) |
| 无修饰符 | 所有类型 | 所有权转移给被调用方 |
### 2.3 数据类型
#### DictionaryRecord → Swift struct
```webidl
dictionary DocumentInfo {
string material_id;
string title;
MaterialType material_type;
u32? page_count; // Optional
string? image_format; // Optional
};
// Rust 侧: #[derive(uniffi::Record)] pub struct DocumentInfo { ... }
// Swift 侧: public struct DocumentInfo { public var materialId: String, ... }
```
**命名规则**
- UDL: `snake_case` → Swift: `camelCase`
- 示例:`material_id``materialId`
#### EnumRust enum → Swift enum
```webidl
[Enum]
interface MaterialType {
Markdown();
Text();
Pdf();
Image();
Epub();
Word();
Excel();
PowerPoint();
Unknown();
};
```
**带数据的枚举**
```webidl
[Enum]
interface ReadingPosition {
Markdown(string block_id, f32 scroll_progress);
Text(u32 line_number, f32 scroll_progress);
Pdf(u32 page_number, f32 page_progress, f32 overall_progress);
Unknown(); // 无数据变体
};
```
#### ErrorRust enum → Swift Error
```webidl
[Error]
enum DocumentError {
"FileNotFound",
"UnsupportedFormat",
"ParseError",
"InvalidEncoding",
"IoError",
};
```
**对应 Rust**
```rust
#[derive(Debug, thiserror::Error, uniffi::Error)]
pub enum DocumentError {
#[error("File not found")] FileNotFound,
#[error("Unsupported format")] UnsupportedFormat,
// ...
}
```
### 2.4 类型映射表
| UDL | Rust | Swift |
|-----|------|-------|
| `string` | `String` | `String` |
| `u32` | `u32` | `UInt32` |
| `u64` | `u64` | `UInt64` |
| `i64` | `i64` | `Int64` |
| `f32` | `f32` | `Float` |
| `boolean` | `bool` | `Bool` |
| `T?` | `Option<T>` | `T?` |
| `sequence<T>` | `Vec<T>` | `[T]` |
| `dictionary` | `#[derive(Record)] struct` | `struct` |
| `[Enum] interface` | `#[derive(Enum)] enum` | `enum` |
| `[Error] enum` | `#[derive(Error)] enum` | `Error` |
---
## 3. 新增类型 Checklist
### 3.1 Rust 侧
1.`zx_document_core/src/` 定义类型
```rust
#[derive(Debug, Clone, Serialize, Deserialize, uniffi::Record)]
pub struct NewType { ... }
```
2. 在 `zx_document_core/src/lib.rs` 添加 `pub mod new_module;`
3. 在 `zx_document_ffi/src/lib.rs` 添加 `pub use zx_document_core::new_module::NewType;`
### 3.2 UDL 侧
1. 在 `zx_document_ffi/src/zx_document.udl` 末尾添加类型定义
2. 如新增函数,在 `namespace zx_document { }` 内声明
### 3.3 代码生成
```bash
# 从 workspace root 执行
cd zhixi-document-runtime
# 生成 Swift 绑定
uniffi-bindgen generate \
crates/zx_document_ffi/src/zx_document.udl \
--language swift \
--out-dir ../ios-projects/AIStudyApp/AIStudyApp/Core/
# 检查生成结果
ls ../ios-projects/AIStudyApp/AIStudyApp/Core/zx_document.swift
```
### 3.4 验证
```bash
# Rust 编译
cargo build --release -p zx_document_ffi
# Rust 测试
cargo test -p zx_document_core
# iOS 编译(在 ios-projects 目录)
xcodebuild build -project AIStudyApp.xcodeproj -scheme AIStudyApp -destination 'platform=iOS Simulator,name=iPhone 16'
```
---
## 4. 常见陷阱
### 4.1 类型未导出
**症状**`error: cannot find type X in this scope`
**原因**Rust 类型未从 `zx_document_ffi` 重新导出
```rust
// zx_document_ffi/src/lib.rs — 必须添加
pub use zx_document_core::new_module::NewType;
```
### 4.2 UDL 字段名不一致
**症状**uniffi-bindgen 报 field name mismatch
**原因**UDL 字段名必须与 Rust struct 字段名一致Rust 用 snake_case → UDL 也用 snake_case
```webidl
dictionary Foo {
string bar_baz; // ✅ 对应 Rust foo.bar_baz
string barBaz; // ❌ 不匹配
};
```
### 4.3 UniFFI 版本兼容
| UniFFI 版本 | Rust crate | CLI |
|:--:|------|-----|
| 0.31 | `uniffi = "0.31"` | `uniffi-bindgen 0.31` |
版本必须一致。检查:
```bash
cargo tree -p zx_document_ffi | grep uniffi
uniffi-bindgen --version
```
### 4.4 Optional 类型
```webidl
// UDL: T? = Rust: Option<T>
u32? page_count; // → Swift: public var pageCount: UInt32?
sequence<string>? items; // → Swift: public var items: [String]?
```
---
## 5. 生成代码结构
```swift
// zx_document.swift (auto-generated by uniffi-bindgen)
// 1. Type definitions
public struct DocumentInfo { ... }
public enum MaterialType { ... }
// 2. Protocol + FFI callback
private protocol zx_documentProtocol { ... }
// 3. Top-level functions
public func detectMaterialType(filePath: String) throws -> MaterialType { ... }
public func buildDocumentInfo(filePath: String, materialId: String, title: String) throws -> DocumentInfo { ... }
// 4. Internal FFI bridge
private var ffi_zx_document_ffi_*: ...;
```
**不要手动修改** `zx_document.swift`。所有修改在 Rust 侧完成后重新生成。
---
## 6. 当前接口统计
| 类别 | 数量 | 示例 |
|------|:--:|------|
| 顶层函数 | 28 | `detect_material_type`, `parse_markdown` |
| Recordstruct | 10 | `DocumentInfo`, `SearchResult` |
| Enum | 7 | `MaterialType`, `ReadingPosition` |
| Error 变体 | 5 | `FileNotFound`, `ParseError` |
| V2 Session 函数 | 6 | `start_reading_session_v2` |
| V2 Event 函数 | 5 | `push_heartbeat_v2` |
| V2 Buffer 函数 | 4 | `export_pending_events_v2` |
---
## 7. 相关文档
- [iOS FFI 调用指南](./ios-ffi-integration-guide.md)
- [文件格式支持矩阵](./file-format-support-matrix.md)
- [Rust FFI 绑定更新流程](../ios-projects/docs/rust-ffi-update.md)ios-projects 仓库)
- [UniFFI 官方文档](https://mozilla.github.io/uniffi-rs/)