Skip to main content

katana_render_runtime/renderer/
runtime_path.rs

1use super::api::{DiagramKind, RenderError};
2use crate::markdown::{
3    drawio_renderer::DrawioRendererOps, mathjax_renderer::MathJaxRendererOps,
4    mermaid_renderer::MermaidBinaryOps, plantuml_renderer::PlantUmlRendererOps,
5};
6use std::path::PathBuf;
7
8pub struct RuntimePathResolver;
9
10impl RuntimePathResolver {
11    pub fn resolve(
12        kind: DiagramKind,
13        runtime_path: Option<PathBuf>,
14    ) -> Result<PathBuf, RenderError> {
15        Self::resolve_with_plantuml_cache_dir(kind, runtime_path, None)
16    }
17
18    pub fn resolve_with_plantuml_cache_dir(
19        kind: DiagramKind,
20        runtime_path: Option<PathBuf>,
21        plantuml_cache_dir: Option<PathBuf>,
22    ) -> Result<PathBuf, RenderError> {
23        if let Some(path) = runtime_path {
24            return Ok(path);
25        }
26        match kind {
27            DiagramKind::Mermaid => MermaidBinaryOps::resolve_mermaid_js(),
28            DiagramKind::Drawio => DrawioRendererOps::resolve_drawio_js(),
29            DiagramKind::MathJax => MathJaxRendererOps::resolve_mathjax_js(),
30            DiagramKind::PlantUml => Ok(plantuml_cache_dir
31                .map_or_else(PlantUmlRendererOps::default_jar_path, |path| {
32                    PlantUmlRendererOps::default_jar_path_for_cache_dir(&path)
33                })),
34        }
35        .map_err(RenderError::RuntimeResolution)
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::RuntimePathResolver;
42    use crate::markdown::plantuml_renderer::PLANTUML_JAR_VERSION;
43    use crate::renderer::api::DiagramKind;
44    use std::path::PathBuf;
45
46    #[test]
47    fn explicit_runtime_path_wins_at_surface_boundary() -> Result<(), Box<dyn std::error::Error>> {
48        let path = PathBuf::from("/tmp/runtime.js");
49        let resolved = RuntimePathResolver::resolve(DiagramKind::Mermaid, Some(path.clone()))?;
50
51        assert_eq!(resolved, path);
52        Ok(())
53    }
54
55    #[test]
56    fn plantuml_cache_dir_can_be_overridden_at_api_boundary()
57    -> Result<(), Box<dyn std::error::Error>> {
58        if std::env::var_os("KRR_PLANTUML_JAR").is_some()
59            || std::env::var_os("KDR_PLANTUML_JAR").is_some()
60            || std::env::var_os("PLANTUML_JAR").is_some()
61        {
62            return Ok(());
63        }
64        let resolved = RuntimePathResolver::resolve_with_plantuml_cache_dir(
65            DiagramKind::PlantUml,
66            None,
67            Some(PathBuf::from("/tmp/krr-api-cache")),
68        )?;
69
70        assert_eq!(
71            resolved,
72            PathBuf::from("/tmp/krr-api-cache")
73                .join(PLANTUML_JAR_VERSION)
74                .join("plantuml.jar")
75        );
76        Ok(())
77    }
78}