synapto_interface/
storage.rs1#![doc = include_str!("storage.md")]
2
3use async_trait::async_trait;
4
5pub trait StorageProviderPool: Send + Sync + 'static {}
7
8#[derive(Default)]
9pub struct StorageRegistry {
10 map: tokio::sync::Mutex<
11 std::collections::HashMap<
12 std::any::TypeId,
13 std::sync::Arc<dyn std::any::Any + Send + Sync>,
14 >,
15 >,
16}
17
18impl StorageRegistry {
19 pub async fn get_or_init<T: StorageProviderPool, F, Fut, E>(
23 &self,
24 init: F,
25 ) -> Result<std::sync::Arc<T>, E>
26 where
27 F: FnOnce() -> Fut,
28 Fut: std::future::Future<Output = Result<T, E>>,
29 {
30 let mut map = self.map.lock().await;
31 let type_id = std::any::TypeId::of::<T>();
32
33 if let Some(resource) = map.get(&type_id) {
34 return Ok(resource
37 .clone()
38 .downcast::<T>()
39 .unwrap_or_else(|_| unreachable!("TypeId mismatch in StorageRegistry")));
40 }
41
42 let resource = std::sync::Arc::new(init().await?);
43 map.insert(type_id, resource.clone());
44 Ok(resource)
45 }
46}
47
48pub trait StorageConfigResolver: Send + Sync + 'static {
49 fn resolve_config(
50 &self,
51 crate_name: &str,
52 storage_type_name: &str,
53 ) -> Option<serde_json::Value>;
54}
55
56#[async_trait]
60pub trait StorageConnection: Send + Sync + Sized + 'static {
61 type Config: serde::de::DeserializeOwned + Send + Sync;
62
63 async fn connect(
64 config: Self::Config,
65 storage_registry: std::sync::Arc<StorageRegistry>,
66 data_dir: &std::path::Path,
67 plugin_namespace: &str,
68 ) -> Result<Self, String>;
69}
70
71use serde::{Deserialize, Serialize, de::DeserializeOwned};
72
73#[derive(Debug, Clone, Serialize, Deserialize, Default)]
74pub struct EmptyStorageConfig {}
75
76#[async_trait]
77pub trait RecordStore: Send + Sync + 'static {
78 async fn upsert_record<T>(&self, collection: &str, key: &str, value: T) -> Result<(), String>
81 where
82 T: Serialize + Send + Sync + 'static;
83
84 async fn get_ordered_records<T>(
87 &self,
88 collection: &str,
89 limit: Option<usize>,
90 reverse: bool,
91 ) -> Result<Vec<(String, T)>, String>
92 where
93 T: DeserializeOwned + Send + Sync + 'static;
94
95 async fn delete_record(&self, collection: &str, key: &str) -> Result<(), String>;
97
98 async fn trim_records_before(&self, collection: &str, cutoff_key: &str) -> Result<(), String>;
101}
102
103#[async_trait]
105pub trait KeyValueStore: Send + Sync + 'static {
106 async fn set<T>(&self, collection: &str, key: &str, value: T) -> Result<(), String>
107 where
108 T: Serialize + Send + Sync + 'static;
109
110 async fn get<T>(&self, collection: &str, key: &str) -> Result<Option<T>, String>
111 where
112 T: DeserializeOwned + Send + Sync + 'static;
113
114 async fn delete(&self, collection: &str, key: &str) -> Result<(), String>;
115
116 async fn get_all<T>(&self, collection: &str) -> Result<Vec<T>, String>
117 where
118 T: DeserializeOwned + Send + Sync + 'static;
119}
120
121#[async_trait]
123pub trait FileStore: Send + Sync + 'static {
124 async fn save_file(
126 &self,
127 collection: &str,
128 file_id: &str,
129 content: Vec<u8>,
130 ) -> Result<(), String>;
131
132 async fn get_file(&self, collection: &str, file_id: &str) -> Result<Option<Vec<u8>>, String>;
134
135 async fn delete_file(&self, collection: &str, file_id: &str) -> Result<(), String>;
137}
138#[async_trait]
139pub trait VectorStore: Send + Sync + 'static {
140 async fn setup_collection(&self, _collection: &str, _dimension: u32) -> Result<(), String> {
153 Ok(())
154 }
155
156 async fn insert_vectors<T>(&self, collection: &str, records: Vec<T>) -> Result<(), String>
157 where
158 T: Serialize + Send + Sync + 'static;
159
160 async fn search_vectors<T>(
161 &self,
162 collection: &str,
163 vector: Vec<f32>,
164 limit: u32,
165 ) -> Result<Vec<T>, String>
166 where
167 T: DeserializeOwned + Send + Sync + 'static;
168
169 async fn delete_vectors(
170 &self,
171 collection: &str,
172 filter_field: &str,
173 filter_value: &str,
174 ) -> Result<(), String>;
175}