paladin_core/base/entity/
node.rs1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use std::hash::{Hash, Hasher};
4use uuid::Uuid;
5
6#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
7pub struct Node<T> {
8 pub uuid: Uuid,
9 pub created: DateTime<Utc>,
10 pub modified: DateTime<Utc>,
11 pub node: T,
12 pub name: Option<String>,
13 pub version: bool,
14}
15
16impl<T> Hash for Node<T>
17where
18 T: Hash,
19{
20 fn hash<H: Hasher>(&self, state: &mut H) {
21 self.uuid.hash(state);
22 self.name.hash(state);
23 self.node.hash(state);
24 }
25}
26
27impl<T> Node<T> {
28 pub fn new(node: T, name: Option<String>) -> Self {
29 let now = Utc::now();
30 Self {
31 uuid: Uuid::new_v4(),
32 created: now,
33 modified: now,
34 node,
35 name,
36 version: true,
37 }
38 }
39
40 pub fn new_with_uuid(uuid: Uuid, node: T, name: Option<String>) -> Self {
41 let now = Utc::now();
42 Self {
43 uuid,
44 created: now,
45 modified: now,
46 node,
47 name,
48 version: true,
49 }
50 }
51
52 pub fn update(&mut self, new_data: T) {
53 self.node = new_data;
54 self.modified = Utc::now();
55 }
56
57 pub fn set_name(&mut self, name: Option<String>) {
58 self.name = name;
59 self.modified = Utc::now();
60 }
61
62 pub fn enable_versioning(&mut self) {
63 self.version = true;
64 self.modified = Utc::now();
65 }
66
67 pub fn disable_versioning(&mut self) {
68 self.version = false;
69 self.modified = Utc::now();
70 }
71
72 pub fn is_versioning_enabled(&self) -> bool {
73 self.version
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80 use serde::{Deserialize, Serialize};
81
82 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
83 struct TestData {
84 value: String,
85 number: u32,
86 }
87
88 #[test]
89 fn test_node_creation() {
90 let test_data = TestData {
91 value: "test".to_string(),
92 number: 42,
93 };
94
95 let node = Node::new(test_data.clone(), Some("Test Node".to_string()));
96
97 assert_eq!(node.node, test_data);
98 assert_eq!(node.name, Some("Test Node".to_string()));
99 assert!(node.version);
100 assert_eq!(node.created, node.modified);
101 }
102
103 #[test]
104 fn test_node_update() {
105 let initial_data = TestData {
106 value: "initial".to_string(),
107 number: 1,
108 };
109
110 let mut node = Node::new(initial_data, None);
111 let initial_modified = node.modified;
112
113 std::thread::sleep(std::time::Duration::from_millis(1));
114
115 let new_data = TestData {
116 value: "updated".to_string(),
117 number: 2,
118 };
119
120 node.update(new_data.clone());
121
122 assert_eq!(node.node, new_data);
123 assert!(node.modified > initial_modified);
124 }
125
126 #[test]
127 fn test_versioning_control() {
128 let test_data = TestData {
129 value: "test".to_string(),
130 number: 42,
131 };
132
133 let mut node = Node::new(test_data, None);
134
135 assert!(node.is_versioning_enabled());
136
137 node.disable_versioning();
138 assert!(!node.is_versioning_enabled());
139
140 node.enable_versioning();
141 assert!(node.is_versioning_enabled());
142 }
143
144 #[test]
145 fn test_node_hash() {
146 let test_data1 = TestData {
147 value: "test1".to_string(),
148 number: 1,
149 };
150
151 let test_data2 = TestData {
152 value: "test2".to_string(),
153 number: 2,
154 };
155
156 let node1 = Node::new(test_data1, Some("Node 1".to_string()));
157 let node2 = Node::new(test_data2, Some("Node 2".to_string()));
158
159 let mut hasher1 = std::collections::hash_map::DefaultHasher::new();
161 let mut hasher2 = std::collections::hash_map::DefaultHasher::new();
162
163 node1.hash(&mut hasher1);
164 node2.hash(&mut hasher2);
165
166 assert_ne!(hasher1.finish(), hasher2.finish());
167 }
168
169 #[test]
170 fn test_node_serialization() -> Result<(), Box<dyn std::error::Error>> {
171 let test_data = TestData {
172 value: "serialize_test".to_string(),
173 number: 100,
174 };
175
176 let node = Node::new(test_data, Some("Serialization Test".to_string()));
177
178 let serialized = serde_json::to_string(&node)?;
180 assert!(!serialized.is_empty());
181
182 let deserialized: Node<TestData> = serde_json::from_str(&serialized)?;
184 assert_eq!(node, deserialized);
185
186 Ok(())
187 }
188}