lc_vector_stores/
provider.rs1use crate::{VectorStore, VectorStoreError};
7use std::sync::Arc;
8
9#[derive(Debug, Clone)]
11pub enum VectorStoreType {
12 InMemory,
14
15 FileBacked {
17 path: String,
19 dimension: usize,
21 },
22
23 Qdrant {
25 url: String,
27 collection: String,
29 },
30}
31
32pub struct VectorStoreProvider;
34
35impl VectorStoreProvider {
36 pub async fn create(
38 store_type: VectorStoreType,
39 ) -> Result<Arc<dyn VectorStore>, VectorStoreError> {
40 match store_type {
41 VectorStoreType::InMemory => {
42 use crate::InMemoryVectorStore;
43 Ok(Arc::new(InMemoryVectorStore::new()))
44 }
45 VectorStoreType::FileBacked { path, dimension } => {
46 use crate::FileVectorStore;
47 let store = FileVectorStore::new(std::path::PathBuf::from(path), dimension)
48 .await
49 .map_err(|e| VectorStoreError::StorageError(e.to_string()))?;
50 Ok(Arc::new(store))
51 }
52 VectorStoreType::Qdrant { url, collection } => {
53 Self::create_qdrant_store(url, collection).await
54 }
55 }
56 }
57
58 async fn create_qdrant_store(
60 url: String,
61 collection: String,
62 ) -> Result<Arc<dyn VectorStore>, VectorStoreError> {
63 #[cfg(feature = "qdrant-integration")]
64 {
65 use crate::{QdrantConfig, QdrantVectorStore};
66 let config = QdrantConfig::new(url, collection);
67 let store = QdrantVectorStore::new(config).await?;
68 Ok(Arc::new(store))
69 }
70
71 #[cfg(not(feature = "qdrant-integration"))]
72 {
73 Err(VectorStoreError::ConnectionError(format!(
76 "Qdrant store requires the 'qdrant-integration' feature (url={url}, collection={collection}); refusing to silently fall back to InMemory, enable the feature in Cargo.toml"
77 )))
78 }
79 }
80}
81
82pub struct VectorStoreBuilder {
84 store_type: VectorStoreType,
85}
86
87impl Default for VectorStoreBuilder {
88 fn default() -> Self {
89 Self::new()
90 }
91}
92
93impl VectorStoreBuilder {
94 pub fn new() -> Self {
96 Self {
97 store_type: VectorStoreType::InMemory,
98 }
99 }
100
101 pub fn in_memory() -> Self {
103 Self {
104 store_type: VectorStoreType::InMemory,
105 }
106 }
107
108 pub fn file_backed(path: impl Into<String>, dimension: usize) -> Self {
110 Self {
111 store_type: VectorStoreType::FileBacked {
112 path: path.into(),
113 dimension,
114 },
115 }
116 }
117
118 pub fn qdrant(url: impl Into<String>, collection: impl Into<String>) -> Self {
120 Self {
121 store_type: VectorStoreType::Qdrant {
122 url: url.into(),
123 collection: collection.into(),
124 },
125 }
126 }
127
128 pub async fn build(self) -> Result<Arc<dyn VectorStore>, VectorStoreError> {
130 VectorStoreProvider::create(self.store_type).await
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137
138 #[tokio::test]
139 async fn test_create_in_memory() {
140 let result = VectorStoreProvider::create(VectorStoreType::InMemory).await;
141 assert!(result.is_ok());
142 }
143
144 #[tokio::test]
145 async fn test_builder_in_memory() {
146 let builder = VectorStoreBuilder::in_memory();
147 let store = builder.build().await;
148 assert!(store.is_ok());
149 }
150
151 #[cfg(not(feature = "qdrant-integration"))]
152 #[tokio::test]
153 async fn test_builder_qdrant_errors_when_feature_disabled() {
154 let builder = VectorStoreBuilder::qdrant("http://localhost:6334", "test_collection");
156 let store = builder.build().await;
157 assert!(store.is_err());
158 }
159}