1use async_trait::async_trait;
2use serde::Serialize;
3use serde::de::DeserializeOwned;
4use std::sync::Arc;
6use std::time::Duration;
7
8use crate::error::CacheError;
9use crate::cache::Cache;
10use super::manager::MemoryManager;
11
12const MAX_KEY_LENGTH: usize = 200;
14
15pub struct PluginMemoryCache {
19 manager: Arc<MemoryManager>,
21
22 plugin_id: String,
24
25 namespace: String,
27}
28
29impl PluginMemoryCache {
30 pub(crate) fn new(manager: Arc<MemoryManager>, plugin_id: String) -> Self {
39 let system_name = manager.system_name();
41 let capacity = system_name.len() + plugin_id.len() + 9; let mut namespace = String::with_capacity(capacity);
43 namespace.push_str(system_name);
44 namespace.push_str(":plugin:");
45 namespace.push_str(&plugin_id);
46 namespace.push(':');
47
48 Self {
49 manager,
50 plugin_id,
51 namespace,
52 }
53 }
54
55 fn build_key(&self, business_key: &str) -> Result<String, CacheError> {
58 self.validate_business_key(business_key)?;
60
61 let capacity = self.namespace.len() + business_key.len();
63 let mut full_key = String::with_capacity(capacity);
64 full_key.push_str(&self.namespace);
65 full_key.push_str(business_key);
66 Ok(full_key)
67 }
68
69 fn validate_business_key(&self, key: &str) -> Result<(), CacheError> {
72 if key.is_empty() {
74 return Err(CacheError::InvalidKey("Key 不能为空".to_string()));
75 }
76
77 if key.len() > MAX_KEY_LENGTH {
79 return Err(CacheError::InvalidKey(
80 format!("Key 长度不能超过 {} 字符", MAX_KEY_LENGTH),
81 ));
82 }
83
84 if key.as_bytes().windows(7).any(|w| w == b"plugin:") {
87 return Err(CacheError::InvalidKey(
88 "Key 不能包含命名空间前缀".to_string(),
89 ));
90 }
91
92 if !key.as_bytes().iter().all(|&b| {
95 matches!(b, b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'_' | b'-' | b':')
96 }) {
97 return Err(CacheError::InvalidKey(
98 "Key 包含非法字符,只允许字母、数字、下划线、连字符、冒号".to_string(),
99 ));
100 }
101
102 Ok(())
103 }
104
105 fn verify_permission(&self, full_key: &str) -> Result<(), CacheError> {
107 if !full_key.starts_with(&self.namespace) {
108 return Err(CacheError::PermissionDenied(
109 "Key 不属于当前插件".to_string(),
110 ));
111 }
112 Ok(())
113 }
114}
115
116#[async_trait]
117impl Cache for PluginMemoryCache {
118 async fn get<T>(&self, key: &str) -> Result<Option<T>, CacheError>
119 where
120 T: DeserializeOwned,
121 {
122 let full_key = self.build_key(key)?;
123 let cache = self.manager.get_cache();
124
125 let json_value = cache.get(&full_key).await;
127
128 match json_value {
132 Some(json) => {
133 let value: T = serde_json::from_str(&json)
134 .map_err(|e| CacheError::DeserializationFailed(e.to_string()))?;
135 Ok(Some(value))
136 }
137 None => Ok(None),
138 }
139 }
140
141 async fn set<T>(&self, key: &str, value: &T, _ttl: Option<Duration>) -> Result<(), CacheError>
142 where
143 T: Serialize + Sync,
144 {
145 let full_key = self.build_key(key)?;
147
148 let json_value = serde_json::to_string(value)
152 .map_err(|e| CacheError::SerializationFailed(e.to_string()))?;
153
154 let cache = self.manager.get_cache();
155
156 cache.insert(full_key.clone(), json_value).await;
161
162 self.manager
164 .add_key_to_index(&self.plugin_id, &full_key);
165
166 Ok(())
167 }
168
169 async fn delete(&self, key: &str) -> Result<bool, CacheError> {
170 let full_key = self.build_key(key)?;
171
172 self.verify_permission(&full_key)?;
174
175 let cache = self.manager.get_cache();
176
177 let deleted = cache.remove(&full_key).await.is_some();
179
180 if deleted {
182 self.manager
183 .remove_key_from_index(&self.plugin_id, &full_key);
184 }
185
186 Ok(deleted)
187 }
188
189 async fn exists(&self, key: &str) -> Result<bool, CacheError> {
190 let full_key = self.build_key(key)?;
191 let cache = self.manager.get_cache();
192
193 let exists = cache.get(&full_key).await.is_some();
195
196 Ok(exists)
197 }
198
199 async fn expire(&self, key: &str, _ttl: Duration) -> Result<bool, CacheError> {
200 let full_key = self.build_key(key)?;
201 let cache = self.manager.get_cache();
202
203 if let Some(value) = cache.get(&full_key).await {
207 cache.insert(full_key, value).await;
208 Ok(true)
209 } else {
210 Ok(false)
211 }
212 }
213
214 async fn ttl(&self, key: &str) -> Result<Option<Duration>, CacheError> {
215 let full_key = self.build_key(key)?;
216 let cache = self.manager.get_cache();
217
218 if cache.get(&full_key).await.is_some() {
222 Ok(None)
224 } else {
225 Ok(None) }
227 }
228
229 async fn clear(&self) -> Result<u64, CacheError> {
230 self.manager.clear_plugin(&self.plugin_id).await
232 }
233
234 async fn clear_module(&self, module: &str) -> Result<u64, CacheError> {
235 self.manager.clear_module(&self.plugin_id, module).await
237 }
238}