这个项目能做什么
# plantuml.rs
[PlantUML](https://plantuml.com/)(Java 图表生成库)的 100% Rust 重实现,目标是与原版行为一致,并通过 FFI 提供 Java、TypeScript 和 Python 语言绑定。
## 状态
**进行中。** 时序图解析、SVG 渲染和 PREPROC(预处理文本)输出已可工作,并已针对 Java 参考实现进行测试。其他图表类型(类图、活动图、用例图等)和渲染后端(PNG、PDF、LaTeX)正在逐步移植。完整路线图见 [`.agents/architecture.md`](.agents/architecture.md)。
## 功能
**当前可用:**
- 时序图解析(`plantuml-sequence`)
- SVG 渲染后端(`plantuml-svg`)
- PREPROC 输出(通过 TIM 引擎生成预处理文本,`plantuml-preproc`)
- 统一渲染 API:`render_svg`、`render_preproc`、`render(source, format)`(`plantuml-engine`)
- 通过 JNI 的 Java 绑定 — `PlantUml.renderSvg` / `PlantUml.renderPreproc`
- 通过 WASM 的 TypeScript 绑定 — `renderSvg` / `renderPreproc`(浏览器 + Node.js)
- 用于布局定位的一维约束求解器(`plantuml-real`)
- 自定义正则引擎(`plantuml-regex`)
- 预处理器:`!include`、`!define`、变量、条件语句(`plantuml-preproc`)
- 命令解析框架(`plantuml-command`)
- 二维图形基元(`plantuml-klimt`)
- 皮肤 / 样式 / 主题系统(`plantuml-skin`)
**计划中:**
- 类图、活动图、用例图及其他图表类型
- PNG、PDF、LaTeX/TikZ 渲染后端
- 布局引擎(Graphviz / ELK)
- CLI 二进制程序(`plantuml-cli`)
- Python 绑定(PyO3 + maturin)
- 用于其他语言绑定的 C FFI 共享库
## 架构
### 流水线
```
源文本
│
▼
BlockUmlBuilder 将输入拆分为 @start/@end 块
│
▼
BlockUml 每个 @start/@end 块对应一个。惰性:TimLoader
预处理(!include、!define、变量)
▼
PSystemBuilder createPSystem() 分发到
图表类型工厂(Sequence、Class、
Activity、UseCase 等)
▼
Diagram 对象 内存中的图表模型
│
▼
Diagram.exportDiagram() 通过 FileFormat 特定的 StringBinder
渲染为 SVG / PNG / PDF / LaTeX / EPS 等
▼
输出字节
```
### Java 包 → Rust crate
| Java 包 | Rust crate | 职责 |
|------------------|------------|---------------|
| `klimt` | `plantuml-klimt` | 二维图形:形状、几何、字体、`StringBounder`、`UGraphic`、`TextBlock` |
| `com.plantuml.ubrex` | `plantuml-regex` | 自定义正则引擎 |
| `preproc` / `tim` | `plantuml-preproc` | 预处理器:`!include`、`!define`、变量、条件语句 |
| `command` | `plantuml-command` | `Command` / `CommandFactory` 解析框架 |
| `abel` / `cucadiagram` | `plantuml-model` | 实体/关系模型:`Entity`、`Link`、`LeafType` |
| `sequencediagram` | `plantuml-sequence` | 时序图 |
| `skin` / `style` / `theme` | `plantuml-skin` | 皮肤 / 样式 / 主题系统 |
| `real` | `plantuml-real` | 用于布局定位的一维约束求解器 |
| `svg` | `plantuml-svg` | SVG 渲染后端 |
| 根(部分) | `plantuml-engine` | `BlockUml`、`BlockUmlBuilder`、`PSystemBuilder`、`SourceStringReader`、统一渲染 API |
| 根(部分) | `plantuml-core` | `Diagram`、`TextBlock`、`StringBounder`、`FileFormat`、`FileFormatOption` |
| — | `plantuml-ffi` | 用于语言绑定的 C FFI 共享库 |
| — | `plantuml-wasm` | 用于 TypeScript 绑定的 WASM 模块(wasm-bindgen) |
### 设计模式
Rust 移植版保留了 Java 原版的关键设计模式:
1. **工厂 + 注册表** — `PSystemBuilder` 通过基于 trait 的注册表分发到各类型的 `*DiagramFactory` 实现。
2. **命令模式** — 每个源行解析器都是注册在 `CommandFactory` 中的 `Command`;映射为带实现的 `Command` trait。
3. **策略** — `FileFormat` 选择渲染后端;布局后端选择(Graphviz 与 ELK)也是策略,使用 trait 对象或枚举。
4. **惰性初始化** — `BlockUml.getDiagram()` 通过 `OnceCell<T>` 或显式 `build()` 调用按需构建模型。
5. **模板方法** — `TitledDiagram` / `Diagram` 定义由子类扩展的基础行为;映射为带默认方法的 trait 和组合。
## 工作区结构
```
plantuml.rs/
├── crates/
│ ├── plantuml-core/ # Diagram、TextBlock、StringBounder、FileFormat
│ ├── plantuml-klimt/ # 二维图形:形状、几何、字体
│ ├── plantuml-regex/ # 自定义正则引擎
│ ├── plantuml-preproc/ # 预处理器:!include、!define、变量
│ ├── plantuml-command/ # Command / CommandFactory 解析框架
│ ├── plantuml-model/ # 实体/关系模型
│ ├── plantuml-engine/ # 顶层流水线和统一渲染 API
│ ├── plantuml-svg/ # SVG 渲染后端
│ ├── plantuml-skin/ # 皮肤 / 样式 / 主题系统
│ ├── plantuml-real/ # 用于布局的一维约束求解器
│ ├── plantuml-sequence/ # 时序图
│ ├── plantuml-ffi/ # C FFI 共享库
│ └── plantuml-wasm/ # WASM 模块(wasm-bindgen)
├── bindings/
│ ├── plantuml-java/ # Java 绑定(JNI)— com.vgerbot.plantuml:plantuml-java
│ └── plantuml-ts/ # TypeScript 绑定(WASM)— @vgerbot/plantuml
├── .agents/ # 代理指南和架构文档
└── Cargo.toml # 工作区清单
```
## 快速开始
### 前置条件
- **Rust 工具链**(edition 2021,`resolver = "2"`)
- **Java 17+** — 仅 Java 绑定需要
- **Node.js** — 仅 TypeScript 绑定需要(在 `bindings/plantuml-ts` 中执行 `npm install`)
### 构建
```sh
cargo build
```
### 测试
```sh
cargo test
```
### 代码检查
```sh
cargo clippy --workspace -- -D warnings
```
## 用法
### Rust
```rust
use plantuml_engine::render_svg;
let svg = render_svg("@startuml\nAlice -> Bob: hello\n@enduml")?;
```
`render` 函数按 `FileFormat` 分发:
```rust
use plantuml_engine::render;
use plantuml_core::FileFormat;
let svg = render("@startuml\nAlice -> Bob: hello\n@enduml", FileFormat::Svg)?;
```
### Java
Maven 坐标:
```xml
<dependency>
<groupId>com.vgerbot.plantuml</groupId>
<artifactId>plantuml-java</artifactId>
<version>0.1.0</version>
</dependency>
```
用法:
```java
import com.vgerbot.plantuml.PlantUml;
String svg = PlantUml.renderSvg("@startuml\nAlice -> Bob: hello\n@enduml");
System.out.println(svg);
```
### TypeScript
安装:
```sh
npm install @vgerbot/plantuml
```
用法(浏览器或 Node.js):
```typescript
import { renderSvg } from '@vgerbot/plantuml';
const svg = await renderSvg('@startuml\nAlice -> Bob: hello\n@enduml');
```
### Python
计划中(PyO3 + maturin)。尚未实现。
## 绑定构建
| 绑定 | 构建命令 |
|---------|-------------|
| Java | `cd bindings/plantuml-java && ./gradlew build` |
| TypeScript | `cd bindings/plantuml-ts && npm run build` |
## 测试
```sh
cargo test --workspace
```
测试直接从 PlantUML Java 参考实现移植:
- **Vega 数据驱动测试** — 带有预期 `.svg` / `.preproc` 输出的 `.puml` 文件,与 Java 参考数据比较。覆盖 38 个时序 SVG 测试以及 `asciiverse/`、`svg/` 和 `mvp/` 套件中的 PREPROC 测试。
- **Nonreg 测试** — 从 Java nonreg 套件移植的回归测试。
- **单元 / 杂项测试** — 各 crate 中 `#[cfg(test)] mod tests` 下的单元测试。
测试数据提交在 `crates/plantuml-engine/tests/resources/vega/` 下。
## 移植指南
移植遵循严格的 1:1 Java → Rust 文件映射:
- **命名**:文件名和方法名从 PascalCase → snake_case;Java 包 → Rust crate 路径。
- **文件映射**:一个 Java 文件 → 一个 Rust 文件;文件大小治理(≤500 / 501–800 / >800 行)。
- **OOP → Rust**:接口 → trait,类 → struct,重载 → 构建器。
- **错误处理**:库使用 `Result` + `thiserror`,CLI 使用 `anyhow`。库代码中不得 panic。
- **文档注释**:所有公共项引用 Java 源,例如 `/// Ported from: net/sourceforge/plantuml/SourceStringReader.java`。
完整细节见 [`.agents/rules/java-to-rust-porting.md`](.agents/rules/java-to-rust-porting.md)。
## 贡献
项目约定见 [`.agents/AGENTS.md`](.agents/AGENTS.md),架构概览、层映射和设计模式见 [`.agents/architecture.md`](.agents/architecture.md)。
## 许可证
MIT 许可证(依据工作区 [`LICENSE`](LICENSE) 文件)。
> **注意:** `Cargo.toml` 在工作区包元数据中声明 `license = "GPL-3.0-only"`,但权威的 `LICENSE` 文件是 MIT。本 README 以 `LICENSE` 文件为准。如果项目意图采用 GPL-3.0,则需要协调 `LICENSE` 文件和 `Cargo.toml` 元数据。
评论
0 评分人数达到10人后显示
登录后参与讨论。