1use std::collections::HashMap;
2
3pub type NodeId = String;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum Direction {
9 LR,
11 RL,
13 TB,
15 BT,
17}
18
19impl Direction {
20 pub fn parse(s: &str) -> Option<Direction> {
22 match s.to_uppercase().as_str() {
23 "LR" => Some(Direction::LR),
24 "RL" => Some(Direction::RL),
25 "TB" | "TD" => Some(Direction::TB),
26 "BT" => Some(Direction::BT),
27 _ => None,
28 }
29 }
30
31 pub fn is_horizontal(&self) -> bool {
33 matches!(self, Direction::LR | Direction::RL)
34 }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
39pub enum NodeShape {
40 #[default]
42 Rectangle,
43 Rounded,
45 Circle,
47 Diamond,
49 Cylinder,
51 Stadium,
53 Subroutine,
55 Hexagon,
57 Parallelogram,
59 ParallelogramAlt,
61 Trapezoid,
63 TrapezoidAlt,
65 Table,
67}
68
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
71pub enum EdgeStyle {
72 #[default]
74 Arrow,
75 Line,
77 DottedArrow,
79 DottedLine,
81 ThickArrow,
83 ThickLine,
85}
86
87#[derive(Debug, Clone)]
89pub struct Subgraph {
90 pub id: String,
91 pub label: String,
92 pub nodes: Vec<NodeId>,
93 pub x: usize,
94 pub y: usize,
95 pub width: usize,
96 pub height: usize,
97}
98
99impl Subgraph {
100 pub fn new(id: String, label: String) -> Self {
101 Self {
102 id,
103 label,
104 nodes: Vec::new(),
105 x: 0,
106 y: 0,
107 width: 0,
108 height: 0,
109 }
110 }
111}
112
113#[derive(Debug, Clone)]
115pub struct Node {
116 pub id: NodeId,
117 pub label: String,
118 pub shape: NodeShape,
119 pub subgraph: Option<String>,
120 pub width: usize,
121 pub height: usize,
122 pub x: usize,
123 pub y: usize,
124}
125
126impl Node {
127 pub fn new(id: NodeId, label: String) -> Self {
129 Self {
130 id,
131 label,
132 shape: NodeShape::default(),
133 subgraph: None,
134 width: 0,
135 height: 0,
136 x: 0,
137 y: 0,
138 }
139 }
140
141 pub fn with_shape(id: NodeId, label: String, shape: NodeShape) -> Self {
143 Self {
144 id,
145 label,
146 shape,
147 subgraph: None,
148 width: 0,
149 height: 0,
150 x: 0,
151 y: 0,
152 }
153 }
154}
155
156#[derive(Debug, Clone, PartialEq, Eq)]
158pub struct Edge {
159 pub from: NodeId,
160 pub to: NodeId,
161 pub label: Option<String>,
162 pub style: EdgeStyle,
163}
164
165#[derive(Debug, Clone)]
167pub struct Graph {
168 pub direction: Direction,
169 pub nodes: HashMap<NodeId, Node>,
170 pub edges: Vec<Edge>,
171 pub subgraphs: Vec<Subgraph>,
172}
173
174impl Graph {
175 pub fn new(direction: Direction) -> Self {
177 Self {
178 direction,
179 nodes: HashMap::new(),
180 edges: Vec::new(),
181 subgraphs: Vec::new(),
182 }
183 }
184}
185
186#[derive(Debug, Clone, Default)]
188pub struct RenderOptions {
189 pub ascii: bool,
191 pub max_width: Option<usize>,
193}