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!(
77 "Qdrant store requires the 'qdrant-integration' feature (url={url}, collection={collection}); refusing to silently fall back to InMemory, enable the feature in Cargo.toml"
78 )))
79 }
80 }
81}
82
83pub struct VectorStoreBuilder {
85 store_type: VectorStoreType,
86}
87
88impl Default for VectorStoreBuilder {
89 fn default() -> Self {
90 Self::new()
91 }
92}
93
94impl VectorStoreBuilder {
95 pub fn new() -> Self {
97 Self {
98 store_type: VectorStoreType::InMemory,
99 }
100 }
101
102 pub fn in_memory() -> Self {
104 Self {
105 store_type: VectorStoreType::InMemory,
106 }
107 }
108
109 pub fn file_backed(path: impl Into<String>, dimension: usize) -> Self {
111 Self {
112 store_type: VectorStoreType::FileBacked {
113 path: path.into(),
114 dimension,
115 },
116 }
117 }
118
119 pub fn qdrant(url: impl Into<String>, collection: impl Into<String>) -> Self {
121 Self {
122 store_type: VectorStoreType::Qdrant {
123 url: url.into(),
124 collection: collection.into(),
125 },
126 }
127 }
128
129 pub async fn build(self) -> Result<Arc<dyn VectorStore>, VectorStoreError> {
131 VectorStoreProvider::create(self.store_type).await
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138
139 #[tokio::test]
140 async fn test_create_in_memory() {
141 let result = VectorStoreProvider::create(VectorStoreType::InMemory).await;
142 assert!(result.is_ok());
143 }
144
145 #[tokio::test]
146 async fn test_builder_in_memory() {
147 let builder = VectorStoreBuilder::in_memory();
148 let store = builder.build().await;
149 assert!(store.is_ok());
150 }
151
152 #[cfg(not(feature = "qdrant-integration"))]
153 #[tokio::test]
154 async fn test_builder_qdrant_errors_when_feature_disabled() {
155 let builder = VectorStoreBuilder::qdrant("http://localhost:6334", "test_collection");
157 let store = builder.build().await;
158 assert!(store.is_err());
159 }
160}