use crate::graph::{VisualEdge, VisualGraph, VisualNode, ShapeHint, NodeType, EdgeStyle};
use rusty_regex::dfa::DFA;
pub fn dfa_to_graph(dfa: &DFA) -> VisualGraph {
use std::collections::HashMap;
let mut graph = VisualGraph::new();
let mut edge_buckets: HashMap<(usize, usize), Vec<(char, EdgeStyle)>> = HashMap::new();
for (id, state) in dfa.states.iter().enumerate() {
let node = VisualNode {
id,
label: format!("{}", id),
is_accept: dfa.accept_states.contains(&id),
shape: ShapeHint::Circle,
node_type: NodeType::Generic,
};
graph.nodes.push(node);
for (&ch, &to) in &state.transitions {
edge_buckets.entry((id, to)).or_default().push((ch, EdgeStyle::Solid));
}
}
for ((from, to), entries) in edge_buckets {
let n = entries.len();
let mid = (n - 1) as f32 / 2.0;
for (i, (ch, style)) in entries.into_iter().enumerate() {
let bend_offset = if n == 1 {
0.0
} else {
(i as f32 - mid) * 0.5
};
graph.edges.push(VisualEdge {
from,
to,
label: ch.to_string(),
style,
bend_offset,
});
}
}
graph
}