1use crate::types::{EdgeId, NodeId, Properties, PropertyValue};
4use bincode::{Decode, Encode};
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7use uuid::Uuid;
8
9#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)]
10pub struct Edge {
11 pub id: EdgeId,
12 pub from: NodeId,
13 pub to: NodeId,
14 pub edge_type: String,
15 pub properties: Properties,
16}
17
18impl Edge {
19 pub fn new(
21 id: EdgeId,
22 from: NodeId,
23 to: NodeId,
24 edge_type: String,
25 properties: Properties,
26 ) -> Self {
27 Self {
28 id,
29 from,
30 to,
31 edge_type,
32 properties,
33 }
34 }
35
36 pub fn create(from: NodeId, to: NodeId, edge_type: impl Into<String>) -> Self {
38 Self {
39 id: Uuid::new_v4().to_string(),
40 from,
41 to,
42 edge_type: edge_type.into(),
43 properties: HashMap::new(),
44 }
45 }
46
47 pub fn get_property(&self, key: &str) -> Option<&PropertyValue> {
49 self.properties.get(key)
50 }
51
52 pub fn set_property(&mut self, key: impl Into<String>, value: PropertyValue) {
54 self.properties.insert(key.into(), value);
55 }
56}
57
58#[derive(Debug, Clone)]
60pub struct EdgeBuilder {
61 id: Option<EdgeId>,
62 from: NodeId,
63 to: NodeId,
64 edge_type: String,
65 properties: Properties,
66}
67
68impl EdgeBuilder {
69 pub fn new(from: NodeId, to: NodeId, edge_type: impl Into<String>) -> Self {
71 Self {
72 id: None,
73 from,
74 to,
75 edge_type: edge_type.into(),
76 properties: HashMap::new(),
77 }
78 }
79
80 pub fn id(mut self, id: impl Into<String>) -> Self {
82 self.id = Some(id.into());
83 self
84 }
85
86 pub fn property<V: Into<PropertyValue>>(mut self, key: impl Into<String>, value: V) -> Self {
88 self.properties.insert(key.into(), value.into());
89 self
90 }
91
92 pub fn properties(mut self, props: Properties) -> Self {
94 self.properties.extend(props);
95 self
96 }
97
98 pub fn build(self) -> Edge {
100 Edge {
101 id: self.id.unwrap_or_else(|| Uuid::new_v4().to_string()),
102 from: self.from,
103 to: self.to,
104 edge_type: self.edge_type,
105 properties: self.properties,
106 }
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113
114 #[test]
115 fn test_edge_builder() {
116 let edge = EdgeBuilder::new("node1".to_string(), "node2".to_string(), "KNOWS")
117 .property("since", 2020i64)
118 .build();
119
120 assert_eq!(edge.from, "node1");
121 assert_eq!(edge.to, "node2");
122 assert_eq!(edge.edge_type, "KNOWS");
123 assert_eq!(
124 edge.get_property("since"),
125 Some(&PropertyValue::Integer(2020))
126 );
127 }
128
129 #[test]
130 fn test_edge_create() {
131 let edge = Edge::create("a".to_string(), "b".to_string(), "FOLLOWS");
132 assert_eq!(edge.from, "a");
133 assert_eq!(edge.to, "b");
134 assert_eq!(edge.edge_type, "FOLLOWS");
135 assert!(edge.properties.is_empty());
136 }
137
138 #[test]
139 fn test_edge_new() {
140 let edge = Edge::new(
141 "e1".to_string(),
142 "n1".to_string(),
143 "n2".to_string(),
144 "LIKES".to_string(),
145 HashMap::new(),
146 );
147 assert_eq!(edge.id, "e1");
148 assert_eq!(edge.edge_type, "LIKES");
149 }
150}