1use serde::{Deserialize, Serialize};
2use std::num::NonZeroUsize;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
6#[serde(rename_all = "snake_case")]
7pub enum RangeIndexDirection {
8 #[default]
10 Asc,
11 Desc,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
17#[serde(rename_all = "snake_case")]
18pub enum VectorDistanceMetric {
19 Cosine,
21 Euclidean,
23 Manhattan,
25}
26
27#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
29#[serde(rename_all = "snake_case")]
30pub enum IndexSpec {
31 NodeEquality {
33 label: String,
35 property: String,
37 #[serde(default)]
39 unique: bool,
40 },
41 NodeRange {
43 label: String,
45 property: String,
47 #[serde(default)]
49 direction: RangeIndexDirection,
50 },
51 EdgeEquality {
53 label: String,
55 property: String,
57 },
58 EdgeRange {
60 label: String,
62 property: String,
64 #[serde(default)]
66 direction: RangeIndexDirection,
67 },
68 NodeVector {
70 label: String,
72 property: String,
74 dimension: NonZeroUsize,
76 metric: VectorDistanceMetric,
78 #[serde(default, skip_serializing_if = "Option::is_none")]
80 tenant_property: Option<String>,
81 },
82 NodeText {
84 label: String,
86 property: String,
88 #[serde(default, skip_serializing_if = "Option::is_none")]
90 tenant_property: Option<String>,
91 },
92 EdgeVector {
94 label: String,
96 property: String,
98 dimension: NonZeroUsize,
100 metric: VectorDistanceMetric,
102 #[serde(default, skip_serializing_if = "Option::is_none")]
104 tenant_property: Option<String>,
105 },
106 EdgeText {
108 label: String,
110 property: String,
112 #[serde(default, skip_serializing_if = "Option::is_none")]
114 tenant_property: Option<String>,
115 },
116}
117
118impl IndexSpec {
119 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 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 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 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 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 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 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 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 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 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 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 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 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}