cypherlite_core/
traits.rs1pub trait TransactionView {
5 fn snapshot_frame(&self) -> u64;
7}
8
9pub trait LabelRegistry {
11 fn get_or_create_label(&mut self, name: &str) -> u32;
13 fn label_id(&self, name: &str) -> Option<u32>;
15 fn label_name(&self, id: u32) -> Option<&str>;
17
18 fn get_or_create_rel_type(&mut self, name: &str) -> u32;
20 fn rel_type_id(&self, name: &str) -> Option<u32>;
22 fn rel_type_name(&self, id: u32) -> Option<&str>;
24
25 fn get_or_create_prop_key(&mut self, name: &str) -> u32;
27 fn prop_key_id(&self, name: &str) -> Option<u32>;
29 fn prop_key_name(&self, id: u32) -> Option<&str>;
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36 use std::collections::HashMap;
37
38 struct MockTxView {
39 frame: u64,
40 }
41
42 impl TransactionView for MockTxView {
43 fn snapshot_frame(&self) -> u64 {
44 self.frame
45 }
46 }
47
48 #[test]
50 fn test_transaction_view_snapshot_frame() {
51 let view = MockTxView { frame: 42 };
52 assert_eq!(view.snapshot_frame(), 42);
53 }
54
55 #[test]
56 fn test_transaction_view_zero_frame() {
57 let view = MockTxView { frame: 0 };
58 assert_eq!(view.snapshot_frame(), 0);
59 }
60
61 #[test]
63 fn test_transaction_view_is_object_safe() {
64 let view: Box<dyn TransactionView> = Box::new(MockTxView { frame: 10 });
65 assert_eq!(view.snapshot_frame(), 10);
66 }
67
68 struct MockRegistry {
71 labels: HashMap<String, u32>,
72 labels_rev: HashMap<u32, String>,
73 label_next: u32,
74 rel_types: HashMap<String, u32>,
75 rel_types_rev: HashMap<u32, String>,
76 rel_next: u32,
77 prop_keys: HashMap<String, u32>,
78 prop_keys_rev: HashMap<u32, String>,
79 prop_next: u32,
80 }
81
82 impl MockRegistry {
83 fn new() -> Self {
84 Self {
85 labels: HashMap::new(),
86 labels_rev: HashMap::new(),
87 label_next: 0,
88 rel_types: HashMap::new(),
89 rel_types_rev: HashMap::new(),
90 rel_next: 0,
91 prop_keys: HashMap::new(),
92 prop_keys_rev: HashMap::new(),
93 prop_next: 0,
94 }
95 }
96 }
97
98 impl LabelRegistry for MockRegistry {
99 fn get_or_create_label(&mut self, name: &str) -> u32 {
100 if let Some(&id) = self.labels.get(name) {
101 return id;
102 }
103 let id = self.label_next;
104 self.label_next += 1;
105 self.labels.insert(name.to_string(), id);
106 self.labels_rev.insert(id, name.to_string());
107 id
108 }
109
110 fn label_id(&self, name: &str) -> Option<u32> {
111 self.labels.get(name).copied()
112 }
113
114 fn label_name(&self, id: u32) -> Option<&str> {
115 self.labels_rev.get(&id).map(|s| s.as_str())
116 }
117
118 fn get_or_create_rel_type(&mut self, name: &str) -> u32 {
119 if let Some(&id) = self.rel_types.get(name) {
120 return id;
121 }
122 let id = self.rel_next;
123 self.rel_next += 1;
124 self.rel_types.insert(name.to_string(), id);
125 self.rel_types_rev.insert(id, name.to_string());
126 id
127 }
128
129 fn rel_type_id(&self, name: &str) -> Option<u32> {
130 self.rel_types.get(name).copied()
131 }
132
133 fn rel_type_name(&self, id: u32) -> Option<&str> {
134 self.rel_types_rev.get(&id).map(|s| s.as_str())
135 }
136
137 fn get_or_create_prop_key(&mut self, name: &str) -> u32 {
138 if let Some(&id) = self.prop_keys.get(name) {
139 return id;
140 }
141 let id = self.prop_next;
142 self.prop_next += 1;
143 self.prop_keys.insert(name.to_string(), id);
144 self.prop_keys_rev.insert(id, name.to_string());
145 id
146 }
147
148 fn prop_key_id(&self, name: &str) -> Option<u32> {
149 self.prop_keys.get(name).copied()
150 }
151
152 fn prop_key_name(&self, id: u32) -> Option<&str> {
153 self.prop_keys_rev.get(&id).map(|s| s.as_str())
154 }
155 }
156
157 #[test]
159 fn test_label_registry_get_or_create_label() {
160 let mut reg = MockRegistry::new();
161 let id1 = reg.get_or_create_label("Person");
162 let id2 = reg.get_or_create_label("Person");
163 assert_eq!(id1, id2, "Same name must return same ID");
164 }
165
166 #[test]
167 fn test_label_registry_different_labels_get_different_ids() {
168 let mut reg = MockRegistry::new();
169 let id1 = reg.get_or_create_label("Person");
170 let id2 = reg.get_or_create_label("Company");
171 assert_ne!(id1, id2);
172 }
173
174 #[test]
175 fn test_label_registry_lookup_by_name() {
176 let mut reg = MockRegistry::new();
177 assert_eq!(reg.label_id("Person"), None);
178 let id = reg.get_or_create_label("Person");
179 assert_eq!(reg.label_id("Person"), Some(id));
180 }
181
182 #[test]
183 fn test_label_registry_lookup_by_id() {
184 let mut reg = MockRegistry::new();
185 assert_eq!(reg.label_name(0), None);
186 let id = reg.get_or_create_label("Person");
187 assert_eq!(reg.label_name(id), Some("Person"));
188 }
189
190 #[test]
192 fn test_label_registry_rel_types() {
193 let mut reg = MockRegistry::new();
194 let id = reg.get_or_create_rel_type("KNOWS");
195 assert_eq!(reg.rel_type_id("KNOWS"), Some(id));
196 assert_eq!(reg.rel_type_name(id), Some("KNOWS"));
197 assert_eq!(reg.get_or_create_rel_type("KNOWS"), id);
198 }
199
200 #[test]
202 fn test_label_registry_prop_keys() {
203 let mut reg = MockRegistry::new();
204 let id = reg.get_or_create_prop_key("name");
205 assert_eq!(reg.prop_key_id("name"), Some(id));
206 assert_eq!(reg.prop_key_name(id), Some("name"));
207 assert_eq!(reg.get_or_create_prop_key("name"), id);
208 }
209
210 #[test]
212 fn test_label_registry_namespaces_are_independent() {
213 let mut reg = MockRegistry::new();
214 let label_id = reg.get_or_create_label("name");
215 let rel_id = reg.get_or_create_rel_type("name");
216 let prop_id = reg.get_or_create_prop_key("name");
217 assert_eq!(reg.label_id("name"), Some(label_id));
220 assert_eq!(reg.rel_type_id("name"), Some(rel_id));
221 assert_eq!(reg.prop_key_id("name"), Some(prop_id));
222 }
223}