Об этом проекте

# 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` необходимо согласовать.