Skip to main content

helix_ast/
index.rs

1use serde::{Deserialize, Serialize};
2use std::num::NonZeroUsize;
3
4/// Physical direction for range indexes.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
6#[serde(rename_all = "snake_case")]
7pub enum RangeIndexDirection {
8    /// Ascending.
9    #[default]
10    Asc,
11    /// Descending.
12    Desc,
13}
14
15/// Vector distance metric for vector index creation.
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
17#[serde(rename_all = "snake_case")]
18pub enum VectorDistanceMetric {
19    /// Cosine similarity.
20    Cosine,
21    /// Euclidean/L2 distance.
22    Euclidean,
23    /// Manhattan/L1 distance.
24    Manhattan,
25}
26
27/// Dynamic index declaration.
28#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
29#[serde(rename_all = "snake_case")]
30pub enum IndexSpec {
31    /// Node equality index.
32    NodeEquality {
33        /// Label scope.
34        label: String,
35        /// Indexed property.
36        property: String,
37        /// Unique index.
38        #[serde(default)]
39        unique: bool,
40    },
41    /// Node range index.
42    NodeRange {
43        /// Label scope.
44        label: String,
45        /// Indexed property.
46        property: String,
47        /// Direction.
48        #[serde(default)]
49        direction: RangeIndexDirection,
50    },
51    /// Edge equality index.
52    EdgeEquality {
53        /// Label scope.
54        label: String,
55        /// Indexed property.
56        property: String,
57    },
58    /// Edge range index.
59    EdgeRange {
60        /// Label scope.
61        label: String,
62        /// Indexed property.
63        property: String,
64        /// Direction.
65        #[serde(default)]
66        direction: RangeIndexDirection,
67    },
68    /// Node vector index.
69    NodeVector {
70        /// Label scope.
71        label: String,
72        /// Indexed property.
73        property: String,
74        /// Vector dimension.
75        dimension: NonZeroUsize,
76        /// Distance metric.
77        metric: VectorDistanceMetric,
78        /// Optional tenant property.
79        #[serde(default, skip_serializing_if = "Option::is_none")]
80        tenant_property: Option<String>,
81    },
82    /// Node text index.
83    NodeText {
84        /// Label scope.
85        label: String,
86        /// Indexed property.
87        property: String,
88        /// Optional tenant property.
89        #[serde(default, skip_serializing_if = "Option::is_none")]
90        tenant_property: Option<String>,
91    },
92    /// Edge vector index.
93    EdgeVector {
94        /// Label scope.
95        label: String,
96        /// Indexed property.
97        property: String,
98        /// Vector dimension.
99        dimension: NonZeroUsize,
100        /// Distance metric.
101        metric: VectorDistanceMetric,
102        /// Optional tenant property.
103        #[serde(default, skip_serializing_if = "Option::is_none")]
104        tenant_property: Option<String>,
105    },
106    /// Edge text index.
107    EdgeText {
108        /// Label scope.
109        label: String,
110        /// Indexed property.
111        property: String,
112        /// Optional tenant property.
113        #[serde(default, skip_serializing_if = "Option::is_none")]
114        tenant_property: Option<String>,
115    },
116}
117
118impl IndexSpec {
119    /// Node equality index.
120    pub fn node_equality(label: impl Into<String>, property: impl Into<String>) -> Self {
121        Self::NodeEquality {
122            label: label.into(),
123            property: property.into(),
124            unique: false,
125        }
126    }
127
128    /// Unique node equality index.
129    pub fn node_unique_equality(label: impl Into<String>, property: impl Into<String>) -> Self {
130        Self::NodeEquality {
131            label: label.into(),
132            property: property.into(),
133            unique: true,
134        }
135    }
136
137    /// Node range index.
138    pub fn node_range(label: impl Into<String>, property: impl Into<String>) -> Self {
139        Self::node_range_with_direction(label, property, RangeIndexDirection::Asc)
140    }
141
142    /// Descending node range index.
143    pub fn node_range_desc(label: impl Into<String>, property: impl Into<String>) -> Self {
144        Self::node_range_with_direction(label, property, RangeIndexDirection::Desc)
145    }
146
147    /// Node range index with direction.
148    pub fn node_range_with_direction(
149        label: impl Into<String>,
150        property: impl Into<String>,
151        direction: RangeIndexDirection,
152    ) -> Self {
153        Self::NodeRange {
154            label: label.into(),
155            property: property.into(),
156            direction,
157        }
158    }
159
160    /// Edge equality index.
161    pub fn edge_equality(label: impl Into<String>, property: impl Into<String>) -> Self {
162        Self::EdgeEquality {
163            label: label.into(),
164            property: property.into(),
165        }
166    }
167
168    /// Edge range index.
169    pub fn edge_range(label: impl Into<String>, property: impl Into<String>) -> Self {
170        Self::edge_range_with_direction(label, property, RangeIndexDirection::Asc)
171    }
172
173    /// Descending edge range index.
174    pub fn edge_range_desc(label: impl Into<String>, property: impl Into<String>) -> Self {
175        Self::edge_range_with_direction(label, property, RangeIndexDirection::Desc)
176    }
177
178    /// Edge range index with direction.
179    pub fn edge_range_with_direction(
180        label: impl Into<String>,
181        property: impl Into<String>,
182        direction: RangeIndexDirection,
183    ) -> Self {
184        Self::EdgeRange {
185            label: label.into(),
186            property: property.into(),
187            direction,
188        }
189    }
190
191    /// Node vector index.
192    pub fn node_vector(
193        label: impl Into<String>,
194        property: impl Into<String>,
195        dimension: NonZeroUsize,
196        metric: VectorDistanceMetric,
197        tenant_property: Option<impl Into<String>>,
198    ) -> Self {
199        Self::NodeVector {
200            label: label.into(),
201            property: property.into(),
202            dimension,
203            metric,
204            tenant_property: tenant_property.map(Into::into),
205        }
206    }
207
208    /// Node text index.
209    pub fn node_text(
210        label: impl Into<String>,
211        property: impl Into<String>,
212        tenant_property: Option<impl Into<String>>,
213    ) -> Self {
214        Self::NodeText {
215            label: label.into(),
216            property: property.into(),
217            tenant_property: tenant_property.map(Into::into),
218        }
219    }
220
221    /// Edge vector index.
222    pub fn edge_vector(
223        label: impl Into<String>,
224        property: impl Into<String>,
225        dimension: NonZeroUsize,
226        metric: VectorDistanceMetric,
227        tenant_property: Option<impl Into<String>>,
228    ) -> Self {
229        Self::EdgeVector {
230            label: label.into(),
231            property: property.into(),
232            dimension,
233            metric,
234            tenant_property: tenant_property.map(Into::into),
235        }
236    }
237
238    /// Edge text index.
239    pub fn edge_text(
240        label: impl Into<String>,
241        property: impl Into<String>,
242        tenant_property: Option<impl Into<String>>,
243    ) -> Self {
244        Self::EdgeText {
245            label: label.into(),
246            property: property.into(),
247            tenant_property: tenant_property.map(Into::into),
248        }
249    }
250}