#![allow(clippy::too_many_arguments)]
#![allow(clippy::collapsible_else_if)]
mod d2_parser;
mod error;
mod grid;
mod layout;
mod parser;
mod pie_parser;
mod renderer;
mod seq_parser;
mod state_parser;
mod types;
pub use error::MermaidError;
pub use layout::{compute_layout, compute_layout_with_options};
pub use types::{
Direction, Edge, EdgeStyle, Graph, Node, NodeId, NodeShape, RenderOptions, RenderResult,
Subgraph,
};
use d2_parser::parse_d2;
use parser::parse_mermaid;
use pie_parser::{parse_pie_chart as parse_pie, render_pie_chart as render_pie};
use renderer::render_graph;
use seq_parser::{parse_sequence_diagram as parse_seq, render_sequence_diagram as render_seq};
use state_parser::parse_state_diagram;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DiagramFormat {
Mermaid,
StateDiagram,
SequenceDiagram,
PieChart,
D2,
}
pub fn detect_format(input: &str) -> DiagramFormat {
let trimmed = input.trim();
let lower = trimmed.to_lowercase();
if lower.starts_with("sequencediagram") {
return DiagramFormat::SequenceDiagram;
}
if lower.starts_with("statediagram") {
return DiagramFormat::StateDiagram;
}
if lower.starts_with("pie") {
return DiagramFormat::PieChart;
}
if trimmed.starts_with("flowchart")
|| trimmed.starts_with("graph ")
|| trimmed.contains("-->")
|| trimmed.contains("-.-")
|| trimmed.contains("==>")
{
return DiagramFormat::Mermaid;
}
DiagramFormat::D2
}
pub fn render_diagram(input: &str, options: RenderOptions) -> Result<RenderResult, MermaidError> {
match detect_format(input) {
DiagramFormat::Mermaid => render_mermaid_to_tui(input, options),
DiagramFormat::StateDiagram => render_state_diagram(input, options),
DiagramFormat::SequenceDiagram => render_sequence_diagram(input, options),
DiagramFormat::PieChart => render_pie_chart(input, options),
DiagramFormat::D2 => render_d2_to_tui(input, options),
}
}
pub fn render_mermaid_to_tui(
input: &str,
options: RenderOptions,
) -> Result<RenderResult, MermaidError> {
let mut graph = parse_mermaid(input)?;
let warnings = compute_layout_with_options(&mut graph, &options);
Ok(RenderResult {
output: render_graph(&graph, &options),
warnings,
})
}
pub fn render_state_diagram(
input: &str,
options: RenderOptions,
) -> Result<RenderResult, MermaidError> {
let mut graph = parse_state_diagram(input)?;
let warnings = compute_layout_with_options(&mut graph, &options);
Ok(RenderResult {
output: render_graph(&graph, &options),
warnings,
})
}
pub fn render_pie_chart(input: &str, options: RenderOptions) -> Result<RenderResult, MermaidError> {
let chart = parse_pie(input)?;
Ok(RenderResult {
output: render_pie(&chart, &options),
warnings: Vec::new(),
})
}
pub fn render_d2_to_tui(input: &str, options: RenderOptions) -> Result<RenderResult, MermaidError> {
let mut graph = parse_d2(input)?;
let warnings = compute_layout_with_options(&mut graph, &options);
Ok(RenderResult {
output: render_graph(&graph, &options),
warnings,
})
}
pub fn render_sequence_diagram(
input: &str,
options: RenderOptions,
) -> Result<RenderResult, MermaidError> {
let diagram = parse_seq(input)?;
Ok(RenderResult {
output: render_seq(&diagram, &options),
warnings: Vec::new(),
})
}