use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Direction {
TD,
LR,
RL,
BT,
}
impl Default for Direction {
fn default() -> Self {
Direction::TD
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Shape {
Rect,
Rounded,
Stadium,
Diamond,
Circle,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EdgeKind {
Arrow,
Open,
Dotted,
Thick,
}
#[derive(Debug, Clone)]
pub struct Node {
pub id: String,
pub label: String,
pub shape: Shape,
}
#[derive(Debug, Clone)]
pub struct Edge {
pub from: usize,
pub to: usize,
pub label: Option<String>,
pub kind: EdgeKind,
}
#[derive(Debug, Default)]
pub struct Graph {
pub direction: Direction,
pub nodes: Vec<Node>,
pub edges: Vec<Edge>,
index: HashMap<String, usize>,
}
impl Graph {
pub fn ensure_node(&mut self, id: &str, label: Option<String>, shape: Option<Shape>) -> usize {
if let Some(&i) = self.index.get(id) {
if let Some(l) = label {
self.nodes[i].label = l;
}
if let Some(s) = shape {
self.nodes[i].shape = s;
}
i
} else {
let i = self.nodes.len();
self.nodes.push(Node {
id: id.to_string(),
label: label.unwrap_or_else(|| id.to_string()),
shape: shape.unwrap_or(Shape::Rect),
});
self.index.insert(id.to_string(), i);
i
}
}
pub fn add_edge(&mut self, from: usize, to: usize, label: Option<String>, kind: EdgeKind) {
self.edges.push(Edge {
from,
to,
label,
kind,
});
}
}