Об этом проекте
# plantuml.rs
Полная переработка [PlantUML](https://plantuml.com/) на 100% Rust — библиотеки генерации диаграмм на Java — с целью достижения поведенческой совместимости, а также языковые привязки для Java, TypeScript и Python через FFI.
## Статус
**В процессе разработки.** Парсинг диаграмм последовательностей, рендеринг 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`)
- Привязка к Java через JNI — `PlantUml.renderSvg` / `PlantUml.renderPreproc`
- Привязка к TypeScript через WASM — `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() Рендеринг через StringBinder, зависящий от FileFormat,
в SVG / PNG / PDF / LaTeX / EPS / и т. д.
▼
Выходные байты
```
### Java-пакет → Rust-крейт
| Java-пакет(ы) | Rust-крейт | Ответственность |
|------------------|------------|---------------|
| `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 |
| root (частично) | `plantuml-engine` | `BlockUml`, `BlockUmlBuilder`, `PSystemBuilder`, `SourceStringReader`, унифицированный API рендеринга |
| root (частично) | `plantuml-core` | `Diagram`, `TextBlock`, `StringBounder`, `FileFormat`, `FileFormatOption` |
| — | `plantuml-ffi` | Разделяемая библиотека C FFI для языковых привязок |
| — | `plantuml-wasm` | Модуль WASM (wasm-bindgen) для привязки к TypeScript |
### Шаблоны проектирования
Порт на Rust сохраняет ключевые шаблоны проектирования из оригинала на Java:
1. **Фабрика + реестр** — `PSystemBuilder` направляет к реализациям `*DiagramFactory` для каждого типа через реестр на основе трейтов.
2. **Шаблон «Команда»** — каждый парсер строки исходного текста — это `Command`, зарегистрированная в `CommandFactory`; сопоставляется с трейтом `Command` и его реализациями.
3. **Стратегия** — `FileFormat` выбирает бэкенд рендеринга; выбор бэкенда компоновки (Graphviz vs ELK) также является стратегией, использующей трейт-объекты или перечисления.
4. **Ленивая инициализация** — `BlockUml.getDiagram()` строит модель по требованию через `OnceCell<T>` или явные вызовы `build()`.
5. **Шаблонный метод** — `TitledDiagram` / `Diagram` определяют базовое поведение, расширяемое подклассами; сопоставляется с трейтами с методами по умолчанию и композицией.
## Структура рабочего пространства
```
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 (`npm install` в `bindings/plantuml-ts`)
### Сборка
```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** — файлы `.puml` с ожидаемым выводом `.svg` / `.preproc`, сравниваемые с эталонными данными Java. Охватывают 38 SVG-тестов диаграмм последовательностей и тесты PREPROC в наборах `asciiverse/`, `svg/` и `mvp/`.
- **Тесты Nonreg** — регрессионные тесты, портированные из набора nonreg на Java.
- **Модульные / прочие тесты** — модульные тесты для каждого крейта в `#[cfg(test)] mod tests`.
Тестовые данные зафиксированы в `crates/plantuml-engine/tests/resources/vega/`.
## Руководство по портированию
Порт следует строгому отображению файлов Java → Rust 1:1:
- **Именование**: PascalCase → snake_case для файлов и методов; Java-пакет → путь крейта Rust.
- **Отображение файлов**: один файл Java → один файл Rust; управление размером файлов (≤500 / 501–800 / >800 строк).
- **ООП → Rust**: интерфейсы → трейты, классы → структуры, перегрузки → билдеры.
- **Обработка ошибок**: `Result` + `thiserror` для библиотек, `anyhow` для CLI. Никаких паник в библиотечном коде.
- **Документирующие комментарии**: все публичные элементы ссылаются на исходник 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` необходимо согласовать.
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.