use serde::{Deserialize, Serialize};
use std::num::NonZeroUsize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
#[serde(rename_all = "snake_case")]
pub enum RangeIndexDirection {
#[default]
Asc,
Desc,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum VectorDistanceMetric {
Cosine,
Euclidean,
Manhattan,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum IndexSpec {
NodeEquality {
label: String,
property: String,
#[serde(default)]
unique: bool,
},
NodeRange {
label: String,
property: String,
#[serde(default)]
direction: RangeIndexDirection,
},
EdgeEquality {
label: String,
property: String,
},
EdgeRange {
label: String,
property: String,
#[serde(default)]
direction: RangeIndexDirection,
},
NodeVector {
label: String,
property: String,
dimension: NonZeroUsize,
metric: VectorDistanceMetric,
#[serde(default, skip_serializing_if = "Option::is_none")]
tenant_property: Option<String>,
},
NodeText {
label: String,
property: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
tenant_property: Option<String>,
},
EdgeVector {
label: String,
property: String,
dimension: NonZeroUsize,
metric: VectorDistanceMetric,
#[serde(default, skip_serializing_if = "Option::is_none")]
tenant_property: Option<String>,
},
EdgeText {
label: String,
property: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
tenant_property: Option<String>,
},
}
impl IndexSpec {
pub fn node_equality(label: impl Into<String>, property: impl Into<String>) -> Self {
Self::NodeEquality {
label: label.into(),
property: property.into(),
unique: false,
}
}
pub fn node_unique_equality(label: impl Into<String>, property: impl Into<String>) -> Self {
Self::NodeEquality {
label: label.into(),
property: property.into(),
unique: true,
}
}
pub fn node_range(label: impl Into<String>, property: impl Into<String>) -> Self {
Self::node_range_with_direction(label, property, RangeIndexDirection::Asc)
}
pub fn node_range_desc(label: impl Into<String>, property: impl Into<String>) -> Self {
Self::node_range_with_direction(label, property, RangeIndexDirection::Desc)
}
pub fn node_range_with_direction(
label: impl Into<String>,
property: impl Into<String>,
direction: RangeIndexDirection,
) -> Self {
Self::NodeRange {
label: label.into(),
property: property.into(),
direction,
}
}
pub fn edge_equality(label: impl Into<String>, property: impl Into<String>) -> Self {
Self::EdgeEquality {
label: label.into(),
property: property.into(),
}
}
pub fn edge_range(label: impl Into<String>, property: impl Into<String>) -> Self {
Self::edge_range_with_direction(label, property, RangeIndexDirection::Asc)
}
pub fn edge_range_desc(label: impl Into<String>, property: impl Into<String>) -> Self {
Self::edge_range_with_direction(label, property, RangeIndexDirection::Desc)
}
pub fn edge_range_with_direction(
label: impl Into<String>,
property: impl Into<String>,
direction: RangeIndexDirection,
) -> Self {
Self::EdgeRange {
label: label.into(),
property: property.into(),
direction,
}
}
pub fn node_vector(
label: impl Into<String>,
property: impl Into<String>,
dimension: NonZeroUsize,
metric: VectorDistanceMetric,
tenant_property: Option<impl Into<String>>,
) -> Self {
Self::NodeVector {
label: label.into(),
property: property.into(),
dimension,
metric,
tenant_property: tenant_property.map(Into::into),
}
}
pub fn node_text(
label: impl Into<String>,
property: impl Into<String>,
tenant_property: Option<impl Into<String>>,
) -> Self {
Self::NodeText {
label: label.into(),
property: property.into(),
tenant_property: tenant_property.map(Into::into),
}
}
pub fn edge_vector(
label: impl Into<String>,
property: impl Into<String>,
dimension: NonZeroUsize,
metric: VectorDistanceMetric,
tenant_property: Option<impl Into<String>>,
) -> Self {
Self::EdgeVector {
label: label.into(),
property: property.into(),
dimension,
metric,
tenant_property: tenant_property.map(Into::into),
}
}
pub fn edge_text(
label: impl Into<String>,
property: impl Into<String>,
tenant_property: Option<impl Into<String>>,
) -> Self {
Self::EdgeText {
label: label.into(),
property: property.into(),
tenant_property: tenant_property.map(Into::into),
}
}
}