Sobre el proyecto
# plantuml.rs
Una reimplementación 100% en Rust de [PlantUML](https://plantuml.com/) —la biblioteca Java de generación de diagramas— con la paridad de comportamiento como objetivo, además de enlaces de lenguaje para Java, TypeScript y Python mediante FFI.
## Estado
**En progreso.** El análisis de diagramas de secuencia, la renderización SVG y la salida PREPROC (texto preprocesado) funcionan y están probados contra la referencia en Java. Otros tipos de diagramas (clases, actividad, casos de uso, etc.) y backends de renderización (PNG, PDF, LaTeX) se están portando de forma incremental. Consulta [`.agents/architecture.md`](.agents/architecture.md) para la hoja de ruta completa.
## Características
**Funciona ahora:**
- Análisis de diagramas de secuencia (`plantuml-sequence`)
- Backend de renderización SVG (`plantuml-svg`)
- Salida PREPROC (texto preprocesado mediante el motor TIM, `plantuml-preproc`)
- API de renderización unificada: `render_svg`, `render_preproc`, `render(source, format)` (`plantuml-engine`)
- Enlace Java mediante JNI — `PlantUml.renderSvg` / `PlantUml.renderPreproc`
- Enlace TypeScript mediante WASM — `renderSvg` / `renderPreproc` (navegador + Node.js)
- Solucionador de restricciones 1D para posicionamiento de diseño (`plantuml-real`)
- Motor de expresiones regulares personalizado (`plantuml-regex`)
- Preprocesador: `!include`, `!define`, variables, condicionales (`plantuml-preproc`)
- Marco de análisis de comandos (`plantuml-command`)
- Primitivas de gráficos 2D (`plantuml-klimt`)
- Sistema de skin / estilo / tema (`plantuml-skin`)
**Planificado:**
- Diagramas de clases, actividad, casos de uso y otros tipos
- Backends de renderización PNG, PDF, LaTeX/TikZ
- Motores de diseño (Graphviz / ELK)
- Binario CLI (`plantuml-cli`)
- Enlace Python (PyO3 + maturin)
- Biblioteca compartida C FFI para enlaces de lenguaje adicionales
## Arquitectura
### Pipeline
```
Texto fuente
│
▼
BlockUmlBuilder Divide la entrada en bloques @start/@end
│
▼
BlockUml Uno por cada bloque @start/@end. Perezoso: TimLoader
preprocesa (!include, !define, variables)
▼
PSystemBuilder createPSystem() despacha a la
fábrica de tipo de diagrama (Sequence, Class,
Activity, UseCase, etc.)
▼
Objeto Diagram El modelo del diagrama en memoria
│
▼
Diagram.exportDiagram() Renderiza mediante un StringBinder específico de FileFormat
a SVG / PNG / PDF / LaTeX / EPS / etc.
▼
Bytes de salida
```
### Paquete Java → Crate de Rust
| Paquete(s) Java | Crate de Rust | Responsabilidad |
|------------------|------------|---------------|
| `klimt` | `plantuml-klimt` | Gráficos 2D: formas, geometría, fuentes, `StringBounder`, `UGraphic`, `TextBlock` |
| `com.plantuml.ubrex` | `plantuml-regex` | Motor de expresiones regulares personalizado |
| `preproc` / `tim` | `plantuml-preproc` | Preprocesador: `!include`, `!define`, variables, condicionales |
| `command` | `plantuml-command` | Marco de análisis `Command` / `CommandFactory` |
| `abel` / `cucadiagram` | `plantuml-model` | Modelo entidad/relación: `Entity`, `Link`, `LeafType` |
| `sequencediagram` | `plantuml-sequence` | Diagrama de secuencia |
| `skin` / `style` / `theme` | `plantuml-skin` | Sistema de skin / estilo / tema |
| `real` | `plantuml-real` | Solucionador de restricciones 1D para posicionamiento de diseño |
| `svg` | `plantuml-svg` | Backend de renderización SVG |
| raíz (parcial) | `plantuml-engine` | `BlockUml`, `BlockUmlBuilder`, `PSystemBuilder`, `SourceStringReader`, API de renderización unificada |
| raíz (parcial) | `plantuml-core` | `Diagram`, `TextBlock`, `StringBounder`, `FileFormat`, `FileFormatOption` |
| — | `plantuml-ffi` | Biblioteca compartida C FFI para enlaces de lenguaje |
| — | `plantuml-wasm` | Módulo WASM (wasm-bindgen) para el enlace TypeScript |
### Patrones de diseño
El port a Rust conserva los patrones de diseño clave del original en Java:
1. **Factory + Registry** — `PSystemBuilder` despacha a implementaciones `*DiagramFactory` por tipo mediante un registro basado en traits.
2. **Patrón Command** — Cada analizador de línea fuente es un `Command` registrado en un `CommandFactory`; se mapea a un trait `Command` con implementaciones.
3. **Strategy** — `FileFormat` selecciona el backend de renderización; la selección del backend de diseño (Graphviz vs ELK) también es una estrategia, usando objetos trait o enums.
4. **Inicialización perezosa** — `BlockUml.getDiagram()` construye el modelo bajo demanda mediante `OnceCell<T>` o llamadas explícitas a `build()`.
5. **Método plantilla** — `TitledDiagram` / `Diagram` definen el comportamiento base extendido por subclases; se mapea a traits con métodos por defecto y composición.
## Estructura del workspace
```
plantuml.rs/
├── crates/
│ ├── plantuml-core/ # Diagram, TextBlock, StringBounder, FileFormat
│ ├── plantuml-klimt/ # Gráficos 2D: formas, geometría, fuentes
│ ├── plantuml-regex/ # Motor de expresiones regulares personalizado
│ ├── plantuml-preproc/ # Preprocesador: !include, !define, variables
│ ├── plantuml-command/ # Marco de análisis Command / CommandFactory
│ ├── plantuml-model/ # Modelo entidad/relación
│ ├── plantuml-engine/ # Pipeline de nivel superior y API de renderización unificada
│ ├── plantuml-svg/ # Backend de renderización SVG
│ ├── plantuml-skin/ # Sistema de skin / estilo / tema
│ ├── plantuml-real/ # Solucionador de restricciones 1D para diseño
│ ├── plantuml-sequence/ # Diagrama de secuencia
│ ├── plantuml-ffi/ # Biblioteca compartida C FFI
│ └── plantuml-wasm/ # Módulo WASM (wasm-bindgen)
├── bindings/
│ ├── plantuml-java/ # Enlace Java (JNI) — com.vgerbot.plantuml:plantuml-java
│ └── plantuml-ts/ # Enlace TypeScript (WASM) — @vgerbot/plantuml
├── .agents/ # Directrices para agentes y documentos de arquitectura
└── Cargo.toml # Manifiesto del workspace
```
## Primeros pasos
### Requisitos previos
- **Toolchain de Rust** (edición 2021, `resolver = "2"`)
- **Java 17+** — solo necesario para el enlace Java
- **Node.js** — solo necesario para el enlace TypeScript (`npm install` en `bindings/plantuml-ts`)
### Compilación
```sh
cargo build
```
### Pruebas
```sh
cargo test
```
### Lint
```sh
cargo clippy --workspace -- -D warnings
```
## Uso
### Rust
```rust
use plantuml_engine::render_svg;
let svg = render_svg("@startuml\nAlice -> Bob: hello\n@enduml")?;
```
La función `render` despacha según `FileFormat`:
```rust
use plantuml_engine::render;
use plantuml_core::FileFormat;
let svg = render("@startuml\nAlice -> Bob: hello\n@enduml", FileFormat::Svg)?;
```
### Java
Coordenadas Maven:
```xml
<dependency>
<groupId>com.vgerbot.plantuml</groupId>
<artifactId>plantuml-java</artifactId>
<version>0.1.0</version>
</dependency>
```
Uso:
```java
import com.vgerbot.plantuml.PlantUml;
String svg = PlantUml.renderSvg("@startuml\nAlice -> Bob: hello\n@enduml");
System.out.println(svg);
```
### TypeScript
Instalación:
```sh
npm install @vgerbot/plantuml
```
Uso (navegador o Node.js):
```typescript
import { renderSvg } from '@vgerbot/plantuml';
const svg = await renderSvg('@startuml\nAlice -> Bob: hello\n@enduml');
```
### Python
Planificado (PyO3 + maturin). Aún no implementado.
## Compilaciones de enlaces
| Enlace | Comando de compilación |
|---------|-------------|
| Java | `cd bindings/plantuml-java && ./gradlew build` |
| TypeScript | `cd bindings/plantuml-ts && npm run build` |
## Pruebas
```sh
cargo test --workspace
```
Las pruebas se portan directamente desde la referencia Java de PlantUML:
- **Pruebas basadas en datos Vega** — archivos `.puml` con salida esperada `.svg` / `.preproc`, comparados con los datos de referencia de Java. Cubre 38 pruebas SVG de secuencia y pruebas PREPROC en las suites `asciiverse/`, `svg/` y `mvp/`.
- **Pruebas nonreg** — pruebas de regresión portadas desde la suite nonreg de Java.
- **Pruebas unitarias / misceláneas** — pruebas unitarias por crate en `#[cfg(test)] mod tests`.
Los datos de prueba están comprometidos en `crates/plantuml-engine/tests/resources/vega/`.
## Directrices de portabilidad
El port sigue un mapeo estricto 1:1 de archivos Java → Rust:
- **Nomenclatura**: PascalCase → snake_case para archivos y métodos; paquete Java → ruta de crate de Rust.
- **Mapeo de archivos**: un archivo Java → un archivo Rust; gobernanza del tamaño de archivo (≤500 / 501–800 / >800 líneas).
- **POO → Rust**: interfaces → traits, clases → structs, sobrecargas → builders.
- **Manejo de errores**: `Result` + `thiserror` para bibliotecas, `anyhow` para CLI. Sin panics en el código de biblioteca.
- **Comentarios de documentación**: todos los elementos públicos citan la fuente Java, p. ej. `/// Ported from: net/sourceforge/plantuml/SourceStringReader.java`.
Consulta [`.agents/rules/java-to-rust-porting.md`](.agents/rules/java-to-rust-porting.md) para más detalles.
## Contribuir
Consulta [`.agents/AGENTS.md`](.agents/AGENTS.md) para las convenciones del proyecto y [`.agents/architecture.md`](.agents/architecture.md) para la visión general de la arquitectura, el mapeo de capas y los patrones de diseño.
## Licencia
Licencia MIT (según el archivo [`LICENSE`](LICENSE) del workspace).
> **Nota:** `Cargo.toml` declara `license = "GPL-3.0-only"` en los metadatos del paquete del workspace, pero el archivo `LICENSE` autoritativo es MIT. Este README refleja el archivo `LICENSE`. Si el proyecto pretende ser GPL-3.0, el archivo `LICENSE` y los metadatos de `Cargo.toml` deben reconciliarse.
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.