use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use uuid::Uuid;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VectorPoint {
pub id: Uuid,
pub vector: Vec<f32>,
pub metadata: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone)]
pub struct SearchResult {
pub id: Uuid,
pub score: f32,
pub metadata: HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone)]
pub struct CollectionConfig {
pub name: String,
pub dimension: usize,
pub distance: DistanceMetric,
}
#[derive(Debug, Clone, Copy)]
pub enum DistanceMetric {
Cosine,
Euclidean,
Dot,
}
impl VectorPoint {
pub fn new(id: Uuid, vector: Vec<f32>) -> Self {
Self {
id,
vector,
metadata: HashMap::new(),
}
}
pub fn with_metadata(mut self, key: impl Into<String>, value: serde_json::Value) -> Self {
self.metadata.insert(key.into(), value);
self
}
pub fn merge_dataset_membership(&mut self, previous: &VectorPoint) {
let mut ids: Vec<String> = Vec::new();
collect_dataset_ids(previous, &mut ids);
collect_dataset_ids(self, &mut ids);
if !ids.is_empty() {
self.metadata.insert(
DATASET_IDS_KEY.to_string(),
serde_json::Value::Array(ids.into_iter().map(serde_json::Value::String).collect()),
);
}
}
}
pub const DATASET_IDS_KEY: &str = "dataset_ids";
pub const DATASET_ID_KEY: &str = "dataset_id";
fn collect_dataset_ids(point: &VectorPoint, out: &mut Vec<String>) {
if let Some(arr) = point
.metadata
.get(DATASET_IDS_KEY)
.and_then(|v| v.as_array())
{
for v in arr {
if let Some(s) = v.as_str()
&& !s.is_empty()
&& !out.iter().any(|x| x == s)
{
out.push(s.to_string());
}
}
}
if let Some(s) = point.metadata.get(DATASET_ID_KEY).and_then(|v| v.as_str())
&& !s.is_empty()
&& !out.iter().any(|x| x == s)
{
out.push(s.to_string());
}
}