1pub mod builder;
8pub mod relationships;
9
10pub use builder::GraphBuilder;
11
12use serde::{Deserialize, Serialize};
13use std::collections::HashMap;
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
17#[serde(rename_all = "camelCase")]
18pub struct GraphData {
19 pub nodes: Vec<GraphNode>,
21
22 pub edges: Vec<GraphEdge>,
24
25 pub clusters: Vec<GraphCluster>,
27}
28
29impl GraphData {
30 pub fn new() -> Self {
32 Self {
33 nodes: Vec::new(),
34 edges: Vec::new(),
35 clusters: Vec::new(),
36 }
37 }
38
39 pub fn add_node(&mut self, node: GraphNode) {
41 self.nodes.push(node);
42 }
43
44 pub fn add_edge(&mut self, edge: GraphEdge) {
46 self.edges.push(edge);
47 }
48
49 pub fn add_cluster(&mut self, cluster: GraphCluster) {
51 self.clusters.push(cluster);
52 }
53
54 pub fn find_node(&self, id: &str) -> Option<&GraphNode> {
56 self.nodes.iter().find(|n| n.id == id)
57 }
58
59 pub fn edges_for_node(&self, node_id: &str) -> Vec<&GraphEdge> {
61 self.edges.iter().filter(|e| e.from == node_id || e.to == node_id).collect()
62 }
63}
64
65impl Default for GraphData {
66 fn default() -> Self {
67 Self::new()
68 }
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
73#[serde(rename_all = "camelCase")]
74pub struct GraphNode {
75 pub id: String,
77
78 pub label: String,
80
81 pub node_type: NodeType,
83
84 pub protocol: Option<Protocol>,
86
87 pub current_state: Option<String>,
89
90 #[serde(default)]
92 pub metadata: HashMap<String, serde_json::Value>,
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
97#[serde(rename_all = "lowercase")]
98pub enum NodeType {
99 Endpoint,
101
102 Service,
104
105 Workspace,
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
111#[serde(rename_all = "lowercase")]
112pub enum Protocol {
113 Http,
115
116 Grpc,
118
119 Websocket,
121
122 Graphql,
124
125 Mqtt,
127
128 Smtp,
130
131 Kafka,
133
134 Amqp,
136
137 Ftp,
139}
140
141impl From<&str> for Protocol {
142 fn from(s: &str) -> Self {
143 match s.to_lowercase().as_str() {
144 "http" => Protocol::Http,
145 "grpc" => Protocol::Grpc,
146 "websocket" => Protocol::Websocket,
147 "graphql" => Protocol::Graphql,
148 "mqtt" => Protocol::Mqtt,
149 "smtp" => Protocol::Smtp,
150 "kafka" => Protocol::Kafka,
151 "amqp" => Protocol::Amqp,
152 "ftp" => Protocol::Ftp,
153 _ => Protocol::Http, }
155 }
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize)]
160#[serde(rename_all = "camelCase")]
161pub struct GraphEdge {
162 pub from: String,
164
165 pub to: String,
167
168 pub edge_type: EdgeType,
170
171 pub label: Option<String>,
173
174 #[serde(default)]
176 pub metadata: HashMap<String, serde_json::Value>,
177}
178
179#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
181#[serde(rename_all = "lowercase")]
182pub enum EdgeType {
183 Dependency,
185
186 StateTransition,
188
189 ServiceCall,
191
192 DataFlow,
194
195 Contains,
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize)]
201#[serde(rename_all = "camelCase")]
202pub struct GraphCluster {
203 pub id: String,
205
206 pub label: String,
208
209 pub cluster_type: ClusterType,
211
212 pub node_ids: Vec<String>,
214
215 #[serde(default)]
217 pub metadata: HashMap<String, serde_json::Value>,
218}
219
220#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
222#[serde(rename_all = "lowercase")]
223pub enum ClusterType {
224 Workspace,
226
227 Service,
229
230 Chain,
232}