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 { url: String, collection: String },
25}
26
27pub struct VectorStoreProvider;
29
30impl VectorStoreProvider {
31 pub async fn create(
33 store_type: VectorStoreType,
34 ) -> Result<Arc<dyn VectorStore>, VectorStoreError> {
35 match store_type {
36 VectorStoreType::InMemory => {
37 use crate::InMemoryVectorStore;
38 Ok(Arc::new(InMemoryVectorStore::new()))
39 }
40 VectorStoreType::FileBacked { path, dimension } => {
41 use crate::FileVectorStore;
42 let store = FileVectorStore::new(std::path::PathBuf::from(path), dimension)
43 .await
44 .map_err(|e| VectorStoreError::StorageError(e.to_string()))?;
45 Ok(Arc::new(store))
46 }
47 VectorStoreType::Qdrant { url, collection } => {
48 Self::create_qdrant_store(url, collection).await
49 }
50 }
51 }
52
53 async fn create_qdrant_store(
55 url: String,
56 collection: String,
57 ) -> Result<Arc<dyn VectorStore>, VectorStoreError> {
58 #[cfg(feature = "qdrant-integration")]
59 {
60 use crate::{QdrantConfig, QdrantVectorStore};
61 let config = QdrantConfig::new(url, collection);
62 let store = QdrantVectorStore::new(config).await?;
63 Ok(Arc::new(store))
64 }
65
66 #[cfg(not(feature = "qdrant-integration"))]
67 {
68 Err(VectorStoreError::ConnectionError(format!(
71 "Qdrant 存储需要启用 'qdrant-integration' feature (url={url}, collection={collection});拒绝静默降级为 InMemory,请在 Cargo.toml 开启该 feature"
72 )))
73 }
74 }
75}
76
77pub struct VectorStoreBuilder {
79 store_type: VectorStoreType,
80}
81
82impl Default for VectorStoreBuilder {
83 fn default() -> Self {
84 Self::new()
85 }
86}
87
88impl VectorStoreBuilder {
89 pub fn new() -> Self {
90 Self {
91 store_type: VectorStoreType::InMemory,
92 }
93 }
94
95 pub fn in_memory() -> Self {
96 Self {
97 store_type: VectorStoreType::InMemory,
98 }
99 }
100
101 pub fn file_backed(path: impl Into<String>, dimension: usize) -> Self {
102 Self {
103 store_type: VectorStoreType::FileBacked {
104 path: path.into(),
105 dimension,
106 },
107 }
108 }
109
110 pub fn qdrant(url: impl Into<String>, collection: impl Into<String>) -> Self {
111 Self {
112 store_type: VectorStoreType::Qdrant {
113 url: url.into(),
114 collection: collection.into(),
115 },
116 }
117 }
118
119 pub async fn build(self) -> Result<Arc<dyn VectorStore>, VectorStoreError> {
120 VectorStoreProvider::create(self.store_type).await
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127
128 #[tokio::test]
129 async fn test_create_in_memory() {
130 let result = VectorStoreProvider::create(VectorStoreType::InMemory).await;
131 assert!(result.is_ok());
132 }
133
134 #[tokio::test]
135 async fn test_builder_in_memory() {
136 let builder = VectorStoreBuilder::in_memory();
137 let store = builder.build().await;
138 assert!(store.is_ok());
139 }
140
141 #[cfg(not(feature = "qdrant-integration"))]
142 #[tokio::test]
143 async fn test_builder_qdrant_errors_when_feature_disabled() {
144 let builder = VectorStoreBuilder::qdrant("http://localhost:6334", "test_collection");
146 let store = builder.build().await;
147 assert!(store.is_err());
148 }
149}