Skip to main content

graphs_tui/
types.rs

1use std::collections::HashMap;
2
3/// Node identifier type
4pub type NodeId = String;
5
6/// Flow direction for the diagram
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum Direction {
9    /// Left to Right
10    LR,
11    /// Right to Left
12    RL,
13    /// Top to Bottom
14    TB,
15    /// Bottom to Top
16    BT,
17}
18
19impl Direction {
20    /// Parse direction from string
21    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    /// Check if direction is horizontal (LR or RL)
32    pub fn is_horizontal(&self) -> bool {
33        matches!(self, Direction::LR | Direction::RL)
34    }
35}
36
37/// Shape of a node
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
39pub enum NodeShape {
40    /// Rectangle [Label]
41    #[default]
42    Rectangle,
43    /// Rounded rectangle (Label)
44    Rounded,
45    /// Circle ((Label))
46    Circle,
47    /// Diamond/rhombus {Label}
48    Diamond,
49    /// Cylinder/database [(Label)]
50    Cylinder,
51    /// Stadium shape ([Label])
52    Stadium,
53    /// Subroutine [[Label]]
54    Subroutine,
55    /// Hexagon {{Label}}
56    Hexagon,
57    /// Parallelogram [/Label/]
58    Parallelogram,
59    /// Reverse Parallelogram [\Label\]
60    ParallelogramAlt,
61    /// Trapezoid [/Label\]
62    Trapezoid,
63    /// Reverse Trapezoid [\Label/]
64    TrapezoidAlt,
65    /// Table (D2 sql_table)
66    Table,
67}
68
69/// Style of an edge/link
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
71pub enum EdgeStyle {
72    /// Solid arrow -->
73    #[default]
74    Arrow,
75    /// Solid line ---
76    Line,
77    /// Dotted arrow -.->
78    DottedArrow,
79    /// Dotted line -.-
80    DottedLine,
81    /// Thick arrow ==>
82    ThickArrow,
83    /// Thick line ===
84    ThickLine,
85}
86
87/// A subgraph/group of nodes
88#[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/// A node in the flowchart
114#[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    /// Create a new node with given id and label
128    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    /// Create a new node with shape
142    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/// An edge connecting two nodes
157#[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/// The complete graph structure
166#[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    /// Create a new empty graph with given direction
176    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/// Options for rendering the diagram
187#[derive(Debug, Clone, Default)]
188pub struct RenderOptions {
189    /// Use ASCII characters instead of Unicode
190    pub ascii: bool,
191    /// Maximum width (not yet implemented)
192    pub max_width: Option<usize>,
193}