Skip to main content

vectorizer_sdk/client/
collections.rs

1//! Collection-management surface: list, create, get info, delete.
2//!
3//! These are the four endpoints that operate on collections as a
4//! whole — vector-level CRUD lives in [`super::vectors`], search
5//! over a collection lives in [`super::search`].
6
7use super::VectorizerClient;
8use crate::error::{Result, VectorizerError};
9use crate::models::*;
10
11impl VectorizerClient {
12    /// List every collection visible to the authenticated principal.
13    /// Accepts both the legacy bare-array response and the newer
14    /// `{collections: [...]}` wrapper.
15    pub async fn list_collections(&self) -> Result<Vec<Collection>> {
16        let response = self.make_request("GET", "/collections", None).await?;
17        let collections: Vec<Collection> = if let Ok(wrapper) =
18            serde_json::from_str::<serde_json::Value>(&response)
19        {
20            if let Some(arr) = wrapper.get("collections").and_then(|v| v.as_array()) {
21                serde_json::from_value(serde_json::Value::Array(arr.clone())).map_err(|e| {
22                    VectorizerError::server(format!("Failed to parse collections array: {e}"))
23                })?
24            } else if wrapper.is_array() {
25                serde_json::from_value(wrapper).map_err(|e| {
26                    VectorizerError::server(format!("Failed to parse collections response: {e}"))
27                })?
28            } else {
29                return Err(VectorizerError::server(
30                    "Unexpected collections response format".to_string(),
31                ));
32            }
33        } else {
34            return Err(VectorizerError::server(
35                "Failed to parse collections response".to_string(),
36            ));
37        };
38        Ok(collections)
39    }
40
41    /// Create a new collection. The returned [`CollectionInfo`] is
42    /// synthesised from the server's create-response plus the
43    /// arguments — the server response only carries the collection
44    /// name today.
45    pub async fn create_collection(
46        &self,
47        name: &str,
48        dimension: usize,
49        metric: Option<SimilarityMetric>,
50    ) -> Result<CollectionInfo> {
51        let mut payload = serde_json::Map::new();
52        payload.insert(
53            "name".to_string(),
54            serde_json::Value::String(name.to_string()),
55        );
56        payload.insert(
57            "dimension".to_string(),
58            serde_json::Value::Number(dimension.into()),
59        );
60        payload.insert(
61            "metric".to_string(),
62            serde_json::Value::String(format!("{:?}", metric.unwrap_or_default()).to_lowercase()),
63        );
64
65        let response = self
66            .make_request(
67                "POST",
68                "/collections",
69                Some(serde_json::Value::Object(payload)),
70            )
71            .await?;
72        let create_response: CreateCollectionResponse =
73            serde_json::from_str(&response).map_err(|e| {
74                VectorizerError::server(format!("Failed to parse create collection response: {e}"))
75            })?;
76
77        let info = CollectionInfo {
78            name: create_response.collection,
79            dimension,
80            metric: format!("{:?}", metric.unwrap_or_default()).to_lowercase(),
81            vector_count: 0,
82            document_count: 0,
83            created_at: String::new(),
84            updated_at: String::new(),
85            indexing_status: Some(crate::models::IndexingStatus {
86                status: "created".to_string(),
87                progress: 0.0,
88                total_documents: 0,
89                processed_documents: 0,
90                vector_count: 0,
91                estimated_time_remaining: None,
92                last_updated: String::new(),
93            }),
94            size: None,
95            quantization: None,
96            normalization: None,
97            status: Some("created".to_string()),
98        };
99        Ok(info)
100    }
101
102    /// Delete a collection by name.
103    pub async fn delete_collection(&self, name: &str) -> Result<()> {
104        self.make_request("DELETE", &format!("/collections/{name}"), None)
105            .await?;
106        Ok(())
107    }
108
109    /// Fetch metadata for a collection (vector count, dimension,
110    /// metric, timestamps, indexing status).
111    pub async fn get_collection_info(&self, collection: &str) -> Result<CollectionInfo> {
112        let response = self
113            .make_request("GET", &format!("/collections/{collection}"), None)
114            .await?;
115        let info: CollectionInfo = serde_json::from_str(&response).map_err(|e| {
116            VectorizerError::server(format!("Failed to parse collection info: {e}"))
117        })?;
118        Ok(info)
119    }
120}