Skip to main content

katana_render_runtime/renderer/backends/
plantuml.rs

1use crate::markdown::color_preset::DiagramColorPreset;
2use crate::markdown::{
3    DiagramBlock,
4    plantuml_renderer::{
5        PlantUmlRendererOps, PlantUmlRuntimeConfig, PlantUmlThemeCatalog, PlantUmlThemeConfig,
6    },
7};
8use crate::renderer::api::{DiagramKind, RenderError, RenderInput, RenderOutput, Renderer};
9use crate::renderer::output::RenderOutputFactory;
10use crate::renderer::runtime::RuntimeDescriptor;
11use std::path::PathBuf;
12
13#[derive(Debug, Clone)]
14pub struct PlantUmlRenderer {
15    jar_path: PathBuf,
16}
17
18impl PlantUmlRenderer {
19    pub fn with_runtime_path(jar_path: PathBuf) -> Self {
20        Self { jar_path }
21    }
22
23    pub fn with_cache_dir(cache_dir: PathBuf) -> Self {
24        Self {
25            jar_path: PlantUmlRendererOps::default_jar_path_for_cache_dir(&cache_dir),
26        }
27    }
28
29    pub fn available_themes() -> &'static [&'static str] {
30        PlantUmlThemeCatalog::names()
31    }
32}
33
34impl Renderer for PlantUmlRenderer {
35    fn render(&self, input: &RenderInput) -> Result<RenderOutput, RenderError> {
36        if input.kind != DiagramKind::PlantUml {
37            return Err(RenderError::UnsupportedKind);
38        }
39        RenderOutputFactory::from_diagram_result(
40            input,
41            self.render_block(input),
42            RuntimeDescriptor::plantuml(),
43        )
44    }
45}
46
47impl PlantUmlRenderer {
48    fn render_block(&self, input: &RenderInput) -> crate::markdown::DiagramResult {
49        let block = DiagramBlock {
50            kind: crate::markdown::DiagramKind::PlantUml,
51            source: input.source.clone(),
52        };
53        let config = match PlantUmlRenderConfig::from_input(input) {
54            Ok(config) => config,
55            Err(error) => {
56                return crate::markdown::DiagramResult::Err {
57                    source: input.source.clone(),
58                    error: format!("invalid PlantUML config: {error}"),
59                };
60            }
61        };
62        let preset = DiagramColorPreset::for_render_input(input);
63        PlantUmlRendererOps::render_plantuml_with_jar_path(
64            &block,
65            &self.jar_path,
66            &preset,
67            &config.theme,
68            &config.runtime,
69        )
70    }
71}
72
73struct PlantUmlRenderConfig {
74    theme: PlantUmlThemeConfig,
75    runtime: PlantUmlRuntimeConfig,
76}
77
78impl PlantUmlRenderConfig {
79    fn from_input(input: &RenderInput) -> Result<Self, String> {
80        Ok(Self {
81            theme: PlantUmlThemeConfig::from_value(&input.config.vendor_config)?,
82            runtime: PlantUmlRuntimeConfig::from_value(&input.config.vendor_config)?,
83        })
84    }
85}