1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use uuid::Uuid;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
7#[serde(tag = "type", rename = "Vertex")]
8pub struct Vertex {
9 pub guid: String,
11 pub name: String,
13 pub attribute: String,
15 pub index: i32,
17}
18
19impl Default for Vertex {
20 fn default() -> Self {
21 Self {
22 name: "my_vertex".to_string(),
23 guid: Uuid::new_v4().to_string(),
24 attribute: String::new(),
25 index: -1,
26 }
27 }
28}
29
30impl Vertex {
31 pub fn new(name: Option<String>, attribute: Option<String>) -> Self {
33 Self {
34 name: name.unwrap_or_default(),
35 attribute: attribute.unwrap_or_default(),
36 ..Default::default()
37 }
38 }
39
40 pub fn to_json_data(&self) -> Result<String, Box<dyn std::error::Error>> {
46 Ok(serde_json::to_string_pretty(self)?)
47 }
48
49 pub fn from_json_data(json_data: &str) -> Result<Self, Box<dyn std::error::Error>> {
51 Ok(serde_json::from_str(json_data)?)
52 }
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
57#[serde(tag = "type", rename = "Edge")]
58pub struct Edge {
59 pub guid: String,
61 pub name: String,
63 pub v0: String,
65 pub v1: String,
67 pub attribute: String,
69 pub index: i32,
71}
72
73impl Default for Edge {
74 fn default() -> Self {
75 Self {
76 name: "my_edge".to_string(),
77 guid: Uuid::new_v4().to_string(),
78 v0: String::new(),
79 v1: String::new(),
80 attribute: String::new(),
81 index: -1,
82 }
83 }
84}
85
86impl Edge {
87 pub fn new(
89 name: Option<String>,
90 v0: Option<String>,
91 v1: Option<String>,
92 attribute: Option<String>,
93 ) -> Self {
94 Self {
95 name: name.unwrap_or_default(),
96 v0: v0.unwrap_or_default(),
97 v1: v1.unwrap_or_default(),
98 attribute: attribute.unwrap_or_default(),
99 ..Default::default()
100 }
101 }
102
103 pub fn to_json_data(&self) -> Result<String, Box<dyn std::error::Error>> {
109 Ok(serde_json::to_string_pretty(self)?)
110 }
111
112 pub fn from_json_data(json_data: &str) -> Result<Self, Box<dyn std::error::Error>> {
114 Ok(serde_json::from_str(json_data)?)
115 }
116
117 pub fn vertices(&self) -> (String, String) {
119 (self.v0.clone(), self.v1.clone())
120 }
121
122 pub fn connects(&self, vertex_id: &str) -> bool {
124 self.v0 == vertex_id || self.v1 == vertex_id
125 }
126
127 pub fn other_vertex(&self, vertex_id: &str) -> String {
129 if self.v0 == vertex_id {
130 self.v1.clone()
131 } else {
132 self.v0.clone()
133 }
134 }
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize)]
138#[serde(tag = "type", rename = "Graph")]
139pub struct Graph {
140 pub guid: String,
142 pub name: String,
143 pub vertex_count: i32,
144 pub edge_count: i32,
145
146 vertices: HashMap<String, Vertex>,
149 edges: HashMap<String, HashMap<String, Edge>>,
150}
151
152impl Default for Graph {
153 fn default() -> Self {
154 Self {
155 guid: Uuid::new_v4().to_string(),
156 name: "my_graph".to_string(),
157 vertex_count: 0,
158 edge_count: 0,
159 vertices: HashMap::new(),
160 edges: HashMap::new(),
161 }
162 }
163}
164
165impl Graph {
166 pub fn new(name: &str) -> Self {
168 Self {
169 name: name.to_string(),
170 ..Default::default()
171 }
172 }
173
174 pub fn has_node(&self, key: &str) -> bool {
176 self.vertices.contains_key(key)
177 }
178
179 pub fn add_node(&mut self, key: &str, attribute: &str) -> String {
181 if self.has_node(key) {
182 return self.vertices.get(key).unwrap().name.clone();
183 }
184
185 let mut vertex = Vertex::new(Some(key.to_string()), Some(attribute.to_string()));
186 vertex.index = self.vertices.len() as i32;
187 self.vertices.insert(key.to_string(), vertex.clone());
188 self.vertex_count = self.vertices.len() as i32;
189 vertex.name
190 }
191
192 pub fn add_edge(&mut self, u: &str, v: &str, attribute: &str) -> (String, String) {
194 if !self.has_node(u) {
196 self.add_node(u, "");
197 }
198 if !self.has_node(v) {
199 self.add_node(v, "");
200 }
201
202 if self.has_edge((u, v)) {
203 return (u.to_string(), v.to_string());
204 }
205
206 let mut edge = Edge::new(
207 Some("my_edge".to_string()),
208 Some(u.to_string()),
209 Some(v.to_string()),
210 Some(attribute.to_string()),
211 );
212 edge.index = self.edge_count;
213
214 self.edges
215 .entry(u.to_string())
216 .or_default()
217 .insert(v.to_string(), edge.clone());
218 self.edges
219 .entry(v.to_string())
220 .or_default()
221 .insert(u.to_string(), edge);
222
223 self.edge_count += 1;
224
225 (u.to_string(), v.to_string())
226 }
227
228 pub fn has_edge(&self, edge: (&str, &str)) -> bool {
230 let (u, v) = edge;
231 self.edges
232 .get(u)
233 .is_some_and(|neighbors| neighbors.contains_key(v))
234 }
235
236 pub fn number_of_vertices(&self) -> usize {
238 self.vertices.len()
239 }
240
241 pub fn number_of_edges(&self) -> usize {
243 let mut count = 0;
244 let mut seen = std::collections::HashSet::new();
245 for (u, neighbors) in &self.edges {
246 for v in neighbors.keys() {
247 let edge = if u < v {
248 (u.clone(), v.clone())
249 } else {
250 (v.clone(), u.clone())
251 };
252 if seen.insert(edge) {
253 count += 1;
254 }
255 }
256 }
257 count
258 }
259
260 pub fn get_vertices(&self) -> Vec<Vertex> {
262 self.vertices.values().cloned().collect()
263 }
264
265 pub fn get_edges(&self) -> Vec<(String, String)> {
267 let mut result = Vec::new();
268 let mut seen = std::collections::HashSet::new();
269 for (u, neighbors) in &self.edges {
270 for v in neighbors.keys() {
271 let edge = if u < v {
272 (u.clone(), v.clone())
273 } else {
274 (v.clone(), u.clone())
275 };
276 if seen.insert(edge.clone()) {
277 result.push(edge);
278 }
279 }
280 }
281 result
282 }
283
284 pub fn neighbors(&self, node: &str) -> Vec<String> {
286 self.edges
287 .get(node)
288 .map_or(Vec::new(), |neighbors| neighbors.keys().cloned().collect())
289 }
290
291 pub fn remove_node(&mut self, key: &str) {
293 if !self.has_node(key) {
294 return;
295 }
296
297 if let Some(neighbors) = self.edges.remove(key) {
298 for neighbor_key in neighbors.keys() {
299 if let Some(neighbor_edges) = self.edges.get_mut(neighbor_key) {
300 neighbor_edges.remove(key);
301 }
302 }
303 }
304
305 self.vertices.remove(key);
306 self.vertex_count = self.vertices.len() as i32;
307 self.edge_count = self.number_of_edges() as i32;
308 }
309
310 pub fn remove_edge(&mut self, edge: (&str, &str)) {
312 let (u, v) = edge;
313 let mut edge_removed = false;
314
315 if let Some(neighbors) = self.edges.get_mut(u) {
316 if neighbors.remove(v).is_some() {
317 edge_removed = true;
318 }
319 }
320 if let Some(neighbors) = self.edges.get_mut(v) {
321 neighbors.remove(u);
322 }
323
324 if edge_removed {
325 self.edge_count = self.number_of_edges() as i32;
326 }
327 }
328
329 pub fn clear(&mut self) {
331 self.vertices.clear();
332 self.edges.clear();
333 self.vertex_count = 0;
334 self.edge_count = 0;
335 }
336
337 pub fn node_attribute(&mut self, node: &str, value: Option<&str>) -> Option<String> {
339 if !self.has_node(node) {
340 return None;
341 }
342 let vertex = self.vertices.get_mut(node).unwrap();
343 if let Some(val) = value {
344 vertex.attribute = val.to_string();
345 Some(vertex.attribute.clone())
346 } else {
347 Some(vertex.attribute.clone())
348 }
349 }
350
351 pub fn to_json_data(&self) -> Result<String, serde_json::Error> {
357 let mut vertices: Vec<&Vertex> = self.vertices.values().collect();
359 vertices.sort_by_key(|v| v.index);
360
361 let mut edges = Vec::new();
363 let mut seen = std::collections::HashSet::new();
364 for (u, neighbors) in &self.edges {
365 for (v, edge) in neighbors {
366 let edge_tuple = if u < v { (u, v) } else { (v, u) };
367 if seen.insert(edge_tuple) {
368 edges.push(edge);
369 }
370 }
371 }
372 edges.sort_by_key(|e| e.index);
373
374 let json_obj = serde_json::json!({
375 "type": "Graph",
376 "name": self.name,
377 "guid": self.guid,
378 "vertices": vertices,
379 "edges": edges,
380 "vertex_count": self.vertex_count,
381 "edge_count": self.edge_count
382 });
383
384 serde_json::to_string_pretty(&json_obj)
385 }
386
387 pub fn from_json_data(json_data: &str) -> Result<Self, serde_json::Error> {
389 let json_obj: serde_json::Value = serde_json::from_str(json_data)?;
390
391 let mut graph = Graph::new(json_obj["name"].as_str().unwrap_or("my_graph"));
392 graph.guid = json_obj["guid"].as_str().unwrap_or("").to_string();
393 graph.vertex_count = json_obj["vertex_count"].as_i64().unwrap_or(0) as i32;
394 graph.edge_count = json_obj["edge_count"].as_i64().unwrap_or(0) as i32;
395
396 if let Some(vertices_array) = json_obj["vertices"].as_array() {
398 for vertex_data in vertices_array {
399 let vertex: Vertex = serde_json::from_value(vertex_data.clone())?;
400 graph.vertices.insert(vertex.name.clone(), vertex);
401 }
402 }
403
404 if let Some(edges_array) = json_obj["edges"].as_array() {
406 for edge_data in edges_array {
407 let edge: Edge = serde_json::from_value(edge_data.clone())?;
408 let u = &edge.v0;
409 let v = &edge.v1;
410
411 graph
412 .edges
413 .entry(u.clone())
414 .or_default()
415 .insert(v.clone(), edge.clone());
416 graph
417 .edges
418 .entry(v.clone())
419 .or_default()
420 .insert(u.clone(), edge);
421 }
422 }
423
424 Ok(graph)
425 }
426
427 pub fn to_json(&self, filepath: &str) -> Result<(), Box<dyn std::error::Error>> {
429 let json_data = self.to_json_data()?;
430 std::fs::write(filepath, json_data)?;
431 Ok(())
432 }
433
434 pub fn from_json(filepath: &str) -> Result<Self, Box<dyn std::error::Error>> {
436 let json_data = std::fs::read_to_string(filepath)?;
437 Self::from_json_data(&json_data).map_err(|e| e.into())
438 }
439
440 pub fn edge_attribute(&mut self, u: &str, v: &str, value: Option<&str>) -> Option<String> {
442 if !self.has_edge((u, v)) {
443 return None;
444 }
445 if let Some(val) = value {
446 let new_attr = val.to_string();
447 if let Some(neighbors) = self.edges.get_mut(u) {
448 if let Some(edge) = neighbors.get_mut(v) {
449 edge.attribute = new_attr.clone();
450 }
451 }
452 if let Some(neighbors) = self.edges.get_mut(v) {
453 if let Some(edge) = neighbors.get_mut(u) {
454 edge.attribute = new_attr.clone();
455 }
456 }
457 Some(new_attr)
458 } else {
459 self.edges
460 .get(u)
461 .and_then(|neighbors| neighbors.get(v))
462 .map(|edge| edge.attribute.clone())
463 }
464 }
465}