这个项目能做什么

# 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` 元数据。