helix_db/utils/
filterable.rs

1use std::collections::HashMap;
2
3use crate::{
4    helix_engine::types::GraphError,
5    utils::{
6        items::{Edge, Node},
7    },
8    protocol:: {
9        return_values::ReturnValue,
10        value::Value,
11    },
12};
13
14#[derive(Debug, Clone)]
15pub enum FilterableType {
16    Node,
17    Edge,
18    Vector,
19}
20
21/// Trait for types that can be filtered based on their properties.
22/// Implemented by both Node and Edge types.
23pub trait Filterable {
24    fn type_name(&self) -> FilterableType;
25
26    fn id(&self) -> &u128;
27
28    fn uuid(&self) -> String;
29
30    fn label(&self) -> &str;
31
32    fn from_node(&self) -> u128;
33
34    fn from_node_uuid(&self) -> String;
35
36    fn to_node(&self) -> u128;
37
38    fn to_node_uuid(&self) -> String;
39
40    fn properties(self) -> Option<HashMap<String, Value>>;
41
42    fn vector_data(&self) -> &[f64];
43    fn score(&self) -> f64;
44
45    fn properties_mut(&mut self) -> &mut Option<HashMap<String, Value>>;
46
47    fn properties_ref(&self) -> &Option<HashMap<String, Value>>;
48
49    fn check_property(&self, key: &str) -> Result<&Value, GraphError>;
50
51    fn find_property<'a>(
52        &'a self,
53        key: &str,
54        secondary_properties: &'a HashMap<String, ReturnValue>,
55        property: &'a mut ReturnValue,
56    ) -> Option<&'a ReturnValue>;
57}
58
59impl Filterable for Node {
60    #[inline(always)]
61    fn type_name(&self) -> FilterableType {
62        FilterableType::Node
63    }
64
65    #[inline(always)]
66    fn id(&self) -> &u128 {
67        &self.id
68    }
69
70    #[inline(always)]
71    fn uuid(&self) -> String {
72        uuid::Uuid::from_u128(self.id).to_string()
73    }
74
75    #[inline(always)]
76    fn label(&self) -> &str {
77        &self.label
78    }
79
80    #[inline(always)]
81    fn from_node(&self) -> u128 {
82        unreachable!()
83    }
84
85    #[inline(always)]
86    fn from_node_uuid(&self) -> String {
87        unreachable!()
88    }
89
90    #[inline(always)]
91    fn to_node(&self) -> u128 {
92        unreachable!()
93    }
94
95    #[inline(always)]
96    fn to_node_uuid(&self) -> String {
97        unreachable!()
98    }
99
100    #[inline(always)]
101    fn vector_data(&self) -> &[f64] {
102        unreachable!()
103    }
104
105    #[inline(always)]
106    fn score(&self) -> f64 {
107        unreachable!()
108    }
109
110    #[inline(always)]
111    fn properties(self) -> Option<HashMap<String, Value>> {
112        self.properties
113    }
114
115    #[inline(always)]
116    fn properties_ref(&self) -> &Option<HashMap<String, Value>> {
117        &self.properties
118    }
119
120    #[inline(always)]
121    fn properties_mut(&mut self) -> &mut Option<HashMap<String, Value>> {
122        &mut self.properties
123    }
124
125    #[inline(always)]
126    fn check_property(&self, key: &str) -> Result<&Value, GraphError> {
127        match &self.properties {
128            Some(properties) => properties
129                .get(key)
130                .ok_or(GraphError::ConversionError(format!(
131                    "Property {} not found",
132                    key
133                ))),
134            None => Err(GraphError::ConversionError(format!(
135                "Property {} not found",
136                key
137            ))),
138        }
139    }
140
141    #[inline(always)]
142    fn find_property<'a>(
143        &'a self,
144        key: &str,
145        secondary_properties: &'a HashMap<String, ReturnValue>,
146        property: &'a mut ReturnValue,
147    ) -> Option<&'a ReturnValue> {
148        match &self.properties {
149            Some(properties) => match properties.get(key) {
150                Some(value) => {
151                    property.clone_from(&ReturnValue::Value(value.clone()));
152                    Some(property)
153                }
154                None => secondary_properties.get(key),
155            },
156            None => secondary_properties.get(key),
157        }
158    }
159}
160
161impl Filterable for Edge {
162    #[inline(always)]
163    fn type_name(&self) -> FilterableType {
164        FilterableType::Edge
165    }
166
167    #[inline(always)]
168    fn id(&self) -> &u128 {
169        &self.id
170    }
171
172    #[inline(always)]
173    fn uuid(&self) -> String {
174        uuid::Uuid::from_u128(self.id).to_string()
175    }
176
177    #[inline(always)]
178    fn label(&self) -> &str {
179        &self.label
180    }
181
182    #[inline(always)]
183    fn from_node(&self) -> u128 {
184        self.from_node
185    }
186
187    #[inline(always)]
188    fn from_node_uuid(&self) -> String {
189        uuid::Uuid::from_u128(self.from_node).to_string()
190    }
191
192    #[inline(always)]
193    fn to_node(&self) -> u128 {
194        self.to_node
195    }
196
197    #[inline(always)]
198    fn to_node_uuid(&self) -> String {
199        uuid::Uuid::from_u128(self.to_node).to_string()
200    }
201
202    #[inline(always)]
203    fn vector_data(&self) -> &[f64] {
204        unreachable!()
205    }
206
207    #[inline(always)]
208    fn score(&self) -> f64 {
209        unreachable!()
210    }
211
212    #[inline(always)]
213    fn properties(self) -> Option<HashMap<String, Value>> {
214        self.properties
215    }
216
217    #[inline(always)]
218    fn properties_ref(&self) -> &Option<HashMap<String, Value>> {
219        &self.properties
220    }
221
222    #[inline(always)]
223    fn properties_mut(&mut self) -> &mut Option<HashMap<String, Value>> {
224        &mut self.properties
225    }
226
227    #[inline(always)]
228    fn check_property(&self, key: &str) -> Result<&Value, GraphError> {
229        match &self.properties {
230            Some(properties) => properties
231                .get(key)
232                .ok_or(GraphError::ConversionError(format!(
233                    "Property {} not found",
234                    key
235                ))),
236            None => Err(GraphError::ConversionError(format!(
237                "Property {} not found",
238                key
239            ))),
240        }
241    }
242
243    #[inline(always)]
244    fn find_property<'a>(
245        &'a self,
246        key: &str,
247        secondary_properties: &'a HashMap<String, ReturnValue>,
248        property: &'a mut ReturnValue,
249    ) -> Option<&'a ReturnValue> {
250        match &self.properties {
251            Some(properties) => match properties.get(key) {
252                Some(value) => {
253                    property.clone_from(&ReturnValue::Value(value.clone()));
254                    Some(property)
255                }
256                None => secondary_properties.get(key),
257            },
258            None => secondary_properties.get(key),
259        }
260    }
261}