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
12pub struct PluginMemoryCache {
16 manager: Arc<MemoryManager>,
18
19 plugin_id: String,
21
22 namespace: String,
24}
25
26impl PluginMemoryCache {
27 pub(crate) fn new(manager: Arc<MemoryManager>, plugin_id: String) -> Self {
36 let namespace = format!("{}:plugin:{}:", manager.system_name(), plugin_id);
37 Self {
38 manager,
39 plugin_id,
40 namespace,
41 }
42 }
43
44 fn build_key(&self, business_key: &str) -> Result<String, CacheError> {
47 self.validate_business_key(business_key)?;
49
50 let capacity = self.namespace.len() + business_key.len();
52 let mut full_key = String::with_capacity(capacity);
53 full_key.push_str(&self.namespace);
54 full_key.push_str(business_key);
55 Ok(full_key)
56 }
57
58 fn validate_business_key(&self, key: &str) -> Result<(), CacheError> {
61 if key.is_empty() {
63 return Err(CacheError::InvalidKey("Key 不能为空".to_string()));
64 }
65
66 if key.len() > 200 {
68 return Err(CacheError::InvalidKey(
69 "Key 长度不能超过 200 字符".to_string(),
70 ));
71 }
72
73 if key.contains("plugin:") {
76 return Err(CacheError::InvalidKey(
77 "Key 不能包含命名空间前缀".to_string(),
78 ));
79 }
80
81 if !key.as_bytes().iter().all(|&b| {
84 b.is_ascii_alphanumeric() || b == b'_' || b == b'-' || b == b':'
85 }) {
86 return Err(CacheError::InvalidKey(
87 "Key 包含非法字符,只允许字母、数字、下划线、连字符、冒号".to_string(),
88 ));
89 }
90
91 Ok(())
92 }
93
94 fn verify_permission(&self, full_key: &str) -> Result<(), CacheError> {
96 if !full_key.starts_with(&self.namespace) {
97 return Err(CacheError::PermissionDenied(
98 "Key 不属于当前插件".to_string(),
99 ));
100 }
101 Ok(())
102 }
103}
104
105#[async_trait]
106impl Cache for PluginMemoryCache {
107 async fn get<T>(&self, key: &str) -> Result<Option<T>, CacheError>
108 where
109 T: DeserializeOwned,
110 {
111 let full_key = self.build_key(key)?;
112 let cache = self.manager.get_cache();
113
114 let json_value = cache.get(&full_key).await;
116
117 match json_value {
119 Some(json) => {
120 let value: T = serde_json::from_str(&json)
121 .map_err(|e| CacheError::DeserializationFailed(e.to_string()))?;
122 Ok(Some(value))
123 }
124 None => Ok(None),
125 }
126 }
127
128 async fn set<T>(&self, key: &str, value: &T, _ttl: Option<Duration>) -> Result<(), CacheError>
129 where
130 T: Serialize + Sync,
131 {
132 let full_key = self.build_key(key)?;
134
135 let json_value = serde_json::to_string(value)
137 .map_err(|e| CacheError::SerializationFailed(e.to_string()))?;
138
139 let cache = self.manager.get_cache();
140
141 cache.insert(full_key.clone(), json_value).await;
145
146 self.manager
148 .add_key_to_index(&self.plugin_id, &full_key);
149
150 Ok(())
151 }
152
153 async fn delete(&self, key: &str) -> Result<bool, CacheError> {
154 let full_key = self.build_key(key)?;
155
156 self.verify_permission(&full_key)?;
158
159 let cache = self.manager.get_cache();
160
161 let deleted = cache.remove(&full_key).await.is_some();
163
164 if deleted {
166 self.manager
167 .remove_key_from_index(&self.plugin_id, &full_key);
168 }
169
170 Ok(deleted)
171 }
172
173 async fn exists(&self, key: &str) -> Result<bool, CacheError> {
174 let full_key = self.build_key(key)?;
175 let cache = self.manager.get_cache();
176
177 let exists = cache.get(&full_key).await.is_some();
179
180 Ok(exists)
181 }
182
183 async fn expire(&self, key: &str, _ttl: Duration) -> Result<bool, CacheError> {
184 let full_key = self.build_key(key)?;
185 let cache = self.manager.get_cache();
186
187 if let Some(value) = cache.get(&full_key).await {
191 cache.insert(full_key, value).await;
192 Ok(true)
193 } else {
194 Ok(false)
195 }
196 }
197
198 async fn ttl(&self, key: &str) -> Result<Option<Duration>, CacheError> {
199 let full_key = self.build_key(key)?;
200 let cache = self.manager.get_cache();
201
202 if cache.get(&full_key).await.is_some() {
206 Ok(None)
208 } else {
209 Ok(None) }
211 }
212
213 async fn clear(&self) -> Result<u64, CacheError> {
214 self.manager.clear_plugin(&self.plugin_id).await
216 }
217
218 async fn clear_module(&self, module: &str) -> Result<u64, CacheError> {
219 self.manager.clear_module(&self.plugin_id, module).await
221 }
222}