Skip to main content

merman_core/diagram/
mod.rs

1use crate::{Error, ParseMetadata, Result};
2use serde_json::Value;
3
4pub type DiagramSemanticParser = fn(code: &str, meta: &ParseMetadata) -> Result<Value>;
5
6#[derive(Debug, Clone, Default)]
7pub struct DiagramRegistry {
8    parsers: std::collections::HashMap<&'static str, DiagramSemanticParser>,
9}
10
11impl DiagramRegistry {
12    pub fn new() -> Self {
13        Self::default()
14    }
15
16    pub fn insert(&mut self, diagram_type: &'static str, parser: DiagramSemanticParser) {
17        self.parsers.insert(diagram_type, parser);
18    }
19
20    pub fn get(&self, diagram_type: &str) -> Option<DiagramSemanticParser> {
21        self.parsers.get(diagram_type).copied()
22    }
23
24    pub fn default_mermaid_11_12_2() -> Self {
25        let mut reg = Self::new();
26
27        reg.insert("error", crate::diagrams::error_diagram::parse_error);
28
29        reg.insert("flowchart-v2", crate::diagrams::flowchart::parse_flowchart);
30        reg.insert("flowchart", crate::diagrams::flowchart::parse_flowchart);
31        reg.insert("flowchart-elk", crate::diagrams::flowchart::parse_flowchart);
32
33        reg.insert("info", crate::diagrams::info::parse_info);
34        reg.insert("pie", crate::diagrams::pie::parse_pie);
35        reg.insert("c4", crate::diagrams::c4::parse_c4);
36        reg.insert(
37            "requirement",
38            crate::diagrams::requirement::parse_requirement,
39        );
40        reg.insert("sequence", crate::diagrams::sequence::parse_sequence);
41        reg.insert("zenuml", crate::diagrams::zenuml::parse_zenuml);
42
43        reg.insert("classDiagram", crate::diagrams::class::parse_class);
44        reg.insert("class", crate::diagrams::class::parse_class);
45
46        reg.insert("er", crate::diagrams::er::parse_er);
47        reg.insert("erDiagram", crate::diagrams::er::parse_er);
48
49        reg.insert("stateDiagram", crate::diagrams::state::parse_state);
50        reg.insert("state", crate::diagrams::state::parse_state);
51
52        reg.insert("mindmap", crate::diagrams::mindmap::parse_mindmap);
53        reg.insert("gantt", crate::diagrams::gantt::parse_gantt);
54        reg.insert("timeline", crate::diagrams::timeline::parse_timeline);
55        reg.insert("journey", crate::diagrams::journey::parse_journey);
56        reg.insert("kanban", crate::diagrams::kanban::parse_kanban);
57        reg.insert(
58            "architecture",
59            crate::diagrams::architecture::parse_architecture,
60        );
61        reg.insert("block", crate::diagrams::block::parse_block);
62        reg.insert("gitGraph", crate::diagrams::git_graph::parse_git_graph);
63        reg.insert(
64            "quadrantChart",
65            crate::diagrams::quadrant_chart::parse_quadrant_chart,
66        );
67        reg.insert("packet", crate::diagrams::packet::parse_packet);
68        reg.insert("radar", crate::diagrams::radar::parse_radar);
69        reg.insert("treemap", crate::diagrams::treemap::parse_treemap);
70        reg.insert("sankey", crate::diagrams::sankey::parse_sankey);
71        reg.insert("xychart", crate::diagrams::xychart::parse_xychart);
72
73        reg
74    }
75}
76
77#[derive(Debug, Clone)]
78pub struct ParsedDiagram {
79    pub meta: ParseMetadata,
80    pub model: Value,
81}
82
83#[derive(Debug, Clone)]
84pub enum RenderSemanticModel {
85    Json(Value),
86    Mindmap(crate::diagrams::mindmap::MindmapDiagramRenderModel),
87    State(crate::diagrams::state::StateDiagramRenderModel),
88    Flowchart(crate::diagrams::flowchart::FlowchartV2Model),
89    Architecture(crate::diagrams::architecture::ArchitectureDiagramRenderModel),
90    Class(crate::models::class_diagram::ClassDiagram),
91}
92
93#[derive(Debug, Clone)]
94pub struct ParsedDiagramRender {
95    pub meta: ParseMetadata,
96    pub model: RenderSemanticModel,
97}
98
99pub fn parse_or_unsupported(
100    registry: &DiagramRegistry,
101    diagram_type: &str,
102    code: &str,
103    meta: &ParseMetadata,
104) -> Result<Value> {
105    let Some(parser) = registry.get(diagram_type) else {
106        return Err(Error::UnsupportedDiagram {
107            diagram_type: diagram_type.to_string(),
108        });
109    };
110    parser(code, meta)
111}