Skip to main content

sz_orm_core/
plugin.rs

1//! 插件系统模块
2//!
3//! 提供 SzOrmPlugin trait 允许第三方扩展 AI 能力/方言/中间件。
4//! 通过 PluginRegistry 管理插件注册 + 加载 + 调用。
5
6use std::collections::HashMap;
7use std::sync::Arc;
8
9use parking_lot::RwLock;
10
11/// 插件元数据
12#[derive(Debug, Clone)]
13pub struct PluginMetadata {
14    /// 插件名称
15    pub name: String,
16    /// 插件版本
17    pub version: String,
18    /// 插件描述
19    pub description: String,
20    /// 插件作者
21    pub author: String,
22}
23
24impl PluginMetadata {
25    /// 创建插件元数据
26    pub fn new(
27        name: impl Into<String>,
28        version: impl Into<String>,
29        description: impl Into<String>,
30    ) -> Self {
31        Self {
32            name: name.into(),
33            version: version.into(),
34            description: description.into(),
35            author: String::new(),
36        }
37    }
38
39    /// 设置作者
40    pub fn with_author(mut self, author: impl Into<String>) -> Self {
41        self.author = author.into();
42        self
43    }
44}
45
46/// AI 能力扩展点
47pub trait AiExtension: Send + Sync {
48    /// 扩展名称
49    fn name(&self) -> &str;
50
51    /// 执行 AI 扩展能力
52    fn execute(&self, input: &str) -> Result<String, PluginError>;
53}
54
55/// 方言扩展点
56pub trait DialectExtension: Send + Sync {
57    /// 方言名称
58    fn dialect_name(&self) -> &str;
59
60    /// 将 SQL 转换为该方言
61    fn translate(&self, sql: &str) -> Result<String, PluginError>;
62}
63
64/// 中间件扩展点
65pub trait MiddlewareExtension: Send + Sync {
66    /// 中间件名称
67    fn name(&self) -> &str;
68
69    /// 前置处理
70    fn before_query(&self, sql: &str) -> Result<String, PluginError>;
71
72    /// 后置处理
73    fn after_query(&self, sql: &str, result: &str) -> Result<String, PluginError>;
74}
75
76/// 插件错误
77#[derive(Debug, Clone)]
78pub enum PluginError {
79    /// 插件未找到
80    NotFound(String),
81    /// 执行失败
82    ExecutionFailed(String),
83    /// 注册失败
84    RegistrationFailed(String),
85}
86
87impl std::fmt::Display for PluginError {
88    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89        match self {
90            PluginError::NotFound(msg) => write!(f, "Plugin not found: {}", msg),
91            PluginError::ExecutionFailed(msg) => write!(f, "Execution failed: {}", msg),
92            PluginError::RegistrationFailed(msg) => write!(f, "Registration failed: {}", msg),
93        }
94    }
95}
96
97impl std::error::Error for PluginError {}
98
99/// SZ-ORM 插件 trait
100///
101/// 允许第三方扩展 AI 能力/方言/中间件。
102pub trait SzOrmPlugin: Send + Sync {
103    /// 插件元数据
104    fn metadata(&self) -> &PluginMetadata;
105
106    /// 初始化插件
107    fn init(&self) -> Result<(), PluginError> {
108        Ok(())
109    }
110
111    /// 获取 AI 扩展(可选)
112    fn ai_extension(&self) -> Option<&dyn AiExtension> {
113        None
114    }
115
116    /// 获取方言扩展(可选)
117    fn dialect_extension(&self) -> Option<&dyn DialectExtension> {
118        None
119    }
120
121    /// 获取中间件扩展(可选)
122    fn middleware_extension(&self) -> Option<&dyn MiddlewareExtension> {
123        None
124    }
125}
126
127/// 插件注册表
128///
129/// 管理插件注册 + 加载 + 调用。
130pub struct PluginRegistry {
131    plugins: RwLock<HashMap<String, Arc<dyn SzOrmPlugin>>>,
132}
133
134impl Default for PluginRegistry {
135    fn default() -> Self {
136        Self::new()
137    }
138}
139
140impl PluginRegistry {
141    /// 创建空注册表
142    pub fn new() -> Self {
143        Self {
144            plugins: RwLock::new(HashMap::new()),
145        }
146    }
147
148    /// 注册插件
149    pub fn register(&self, plugin: Arc<dyn SzOrmPlugin>) -> Result<(), PluginError> {
150        let metadata = plugin.metadata();
151        let name = metadata.name.clone();
152
153        plugin.init()?;
154
155        let mut plugins = self.plugins.write();
156        if plugins.contains_key(&name) {
157            return Err(PluginError::RegistrationFailed(format!(
158                "插件 {} 已存在",
159                name
160            )));
161        }
162        plugins.insert(name, plugin);
163        Ok(())
164    }
165
166    /// 注销插件
167    pub fn unregister(&self, name: &str) -> Result<(), PluginError> {
168        let mut plugins = self.plugins.write();
169        plugins
170            .remove(name)
171            .ok_or_else(|| PluginError::NotFound(name.to_string()))?;
172        Ok(())
173    }
174
175    /// 获取插件
176    pub fn get(&self, name: &str) -> Option<Arc<dyn SzOrmPlugin>> {
177        self.plugins.read().get(name).cloned()
178    }
179
180    /// 列出所有插件名
181    pub fn list(&self) -> Vec<String> {
182        self.plugins.read().keys().cloned().collect()
183    }
184
185    /// 插件数量
186    pub fn len(&self) -> usize {
187        self.plugins.read().len()
188    }
189
190    /// 是否为空
191    pub fn is_empty(&self) -> bool {
192        self.plugins.read().is_empty()
193    }
194
195    /// 调用 AI 扩展
196    pub fn execute_ai(&self, plugin_name: &str, input: &str) -> Result<String, PluginError> {
197        let plugin = self
198            .get(plugin_name)
199            .ok_or_else(|| PluginError::NotFound(plugin_name.to_string()))?;
200        let ext = plugin
201            .ai_extension()
202            .ok_or_else(|| PluginError::ExecutionFailed("插件无 AI 扩展".to_string()))?;
203        ext.execute(input)
204    }
205
206    /// 调用方言扩展
207    pub fn translate_dialect(&self, plugin_name: &str, sql: &str) -> Result<String, PluginError> {
208        let plugin = self
209            .get(plugin_name)
210            .ok_or_else(|| PluginError::NotFound(plugin_name.to_string()))?;
211        let ext = plugin
212            .dialect_extension()
213            .ok_or_else(|| PluginError::ExecutionFailed("插件无方言扩展".to_string()))?;
214        ext.translate(sql)
215    }
216
217    /// 调用中间件前置处理
218    pub fn before_query(&self, plugin_name: &str, sql: &str) -> Result<String, PluginError> {
219        let plugin = self
220            .get(plugin_name)
221            .ok_or_else(|| PluginError::NotFound(plugin_name.to_string()))?;
222        let ext = plugin
223            .middleware_extension()
224            .ok_or_else(|| PluginError::ExecutionFailed("插件无中间件扩展".to_string()))?;
225        ext.before_query(sql)
226    }
227
228    /// 调用中间件后置处理
229    pub fn after_query(
230        &self,
231        plugin_name: &str,
232        sql: &str,
233        result: &str,
234    ) -> Result<String, PluginError> {
235        let plugin = self
236            .get(plugin_name)
237            .ok_or_else(|| PluginError::NotFound(plugin_name.to_string()))?;
238        let ext = plugin
239            .middleware_extension()
240            .ok_or_else(|| PluginError::ExecutionFailed("插件无中间件扩展".to_string()))?;
241        ext.after_query(sql, result)
242    }
243}