1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
use serde::{Deserialize, Serialize};
use crate::metadata::PluginMetadata;
/// 插件状态
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum PluginStatus {
/// 已加载但未初始化
Loaded,
/// 已初始化但未启动
Initialized,
/// 正在运行
Running,
/// 已停止
Stopped,
/// 已禁用(不处理请求)
Disabled,
/// 错误状态
Error(String),
}
impl PluginStatus {
/// 检查是否可以初始化
///
/// 检查插件当前状态是否允许执行初始化操作。
///
/// # 返回值
/// * `bool` - 如果状态为 `Loaded` 返回 `true`,否则返回 `false`
///
/// # 状态要求
/// 只有 `Loaded` 状态的插件可以初始化。
///
/// # 示例
/// ```no_run
/// if status.can_initialize() {
/// // 可以初始化
/// }
/// ```
pub fn can_initialize(&self) -> bool {
matches!(self, PluginStatus::Loaded)
}
/// 检查是否可以启动
///
/// 检查插件当前状态是否允许执行启动操作。
///
/// # 返回值
/// * `bool` - 如果状态为 `Initialized` 或 `Stopped` 返回 `true`,否则返回 `false`
///
/// # 状态要求
/// `Initialized` 和 `Stopped` 状态的插件可以启动。
///
/// # 示例
/// ```no_run
/// if status.can_start() {
/// // 可以启动
/// }
/// ```
pub fn can_start(&self) -> bool {
matches!(self, PluginStatus::Initialized | PluginStatus::Stopped)
}
/// 检查是否可以停止
///
/// 检查插件当前状态是否允许执行停止操作。
///
/// # 返回值
/// * `bool` - 如果状态为 `Running` 返回 `true`,否则返回 `false`
///
/// # 状态要求
/// 只有 `Running` 状态的插件可以停止。
///
/// # 示例
/// ```no_run
/// if status.can_stop() {
/// // 可以停止
/// }
/// ```
pub fn can_stop(&self) -> bool {
matches!(self, PluginStatus::Running)
}
/// 检查是否正在运行
///
/// 检查插件是否处于运行状态。
///
/// # 返回值
/// * `bool` - 如果状态为 `Running` 返回 `true`,否则返回 `false`
///
/// # 示例
/// ```no_run
/// if status.is_running() {
/// println!("插件正在运行");
/// }
/// ```
pub fn is_running(&self) -> bool {
matches!(self, PluginStatus::Running)
}
/// 检查是否处于错误状态
///
/// 检查插件是否处于错误状态。
///
/// # 返回值
/// * `bool` - 如果状态为 `Error` 返回 `true`,否则返回 `false`
///
/// # 示例
/// ```no_run
/// if status.is_error() {
/// println!("插件处于错误状态");
/// }
/// ```
pub fn is_error(&self) -> bool {
matches!(self, PluginStatus::Error(_))
}
/// 获取状态的字符串表示
///
/// 返回状态的英文字符串表示,用于日志记录和序列化。
///
/// # 返回值
/// * `&str` - 状态的字符串表示:
/// - `Loaded` -> "loaded"
/// - `Initialized` -> "initialized"
/// - `Running` -> "running"
/// - `Stopped` -> "stopped"
/// - `Disabled` -> "disabled"
/// - `Error(_)` -> "error"
///
/// # 示例
/// ```no_run
/// println!("插件状态: {}", status.as_str());
/// ```
pub fn as_str(&self) -> &str {
match self {
PluginStatus::Loaded => "loaded",
PluginStatus::Initialized => "initialized",
PluginStatus::Running => "running",
PluginStatus::Stopped => "stopped",
PluginStatus::Disabled => "disabled",
PluginStatus::Error(_) => "error",
}
}
/// 验证状态转换是否有效
///
/// # 参数
/// * `target` - 目标状态
///
/// # 返回值
/// * `Result<(), String>` - 成功返回 Ok(()),失败返回错误信息
pub fn validate_transition(&self, target: &PluginStatus) -> Result<(), String> {
match (self, target) {
// 从 Loaded 可以转换到 Initialized, Disabled 或 Error
(PluginStatus::Loaded, PluginStatus::Initialized) => Ok(()),
(PluginStatus::Loaded, PluginStatus::Disabled) => Ok(()),
(PluginStatus::Loaded, PluginStatus::Error(_)) => Ok(()),
// 从 Initialized 可以转换到 Running, Stopped, Disabled 或 Error
(PluginStatus::Initialized, PluginStatus::Running) => Ok(()),
(PluginStatus::Initialized, PluginStatus::Stopped) => Ok(()),
(PluginStatus::Initialized, PluginStatus::Disabled) => Ok(()),
(PluginStatus::Initialized, PluginStatus::Error(_)) => Ok(()),
// 从 Running 可以转换到 Stopped, Disabled 或 Error
(PluginStatus::Running, PluginStatus::Stopped) => Ok(()),
(PluginStatus::Running, PluginStatus::Disabled) => Ok(()),
(PluginStatus::Running, PluginStatus::Error(_)) => Ok(()),
// 从 Stopped 可以转换到 Running, Disabled 或 Error
(PluginStatus::Stopped, PluginStatus::Running) => Ok(()),
(PluginStatus::Stopped, PluginStatus::Disabled) => Ok(()),
(PluginStatus::Stopped, PluginStatus::Error(_)) => Ok(()),
// 从 Disabled 可以恢复到 Running, Stopped 或 Error
(PluginStatus::Disabled, PluginStatus::Running) => Ok(()),
(PluginStatus::Disabled, PluginStatus::Stopped) => Ok(()),
(PluginStatus::Disabled, PluginStatus::Error(_)) => Ok(()),
// 从 Error 可以恢复到任何状态
(PluginStatus::Error(_), _) => Ok(()),
// 其他转换无效
_ => Err(format!("无效的状态转换: {} -> {}", self.as_str(), target.as_str())),
}
}
}
impl std::fmt::Display for PluginStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PluginStatus::Loaded => write!(f, "已加载"),
PluginStatus::Initialized => write!(f, "已初始化"),
PluginStatus::Running => write!(f, "运行中"),
PluginStatus::Stopped => write!(f, "已停止"),
PluginStatus::Disabled => write!(f, "已禁用"),
PluginStatus::Error(msg) => write!(f, "错误: {}", msg),
}
}
}
/// 子插件描述信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChildPluginInfo {
/// 子插件 ID
pub id: String,
/// 子插件名称
pub name: String,
/// 子插件版本
pub version: String,
/// 子插件路由前缀
pub route_prefix: Option<String>,
/// 子插件是否为中间插件(用于分层展示)
pub is_middle_plugin: bool,
}
impl ChildPluginInfo {
/// 从插件元数据创建子插件信息
///
/// 从插件的元数据中提取子插件信息,用于在父插件中记录子插件。
///
/// # 参数
/// * `metadata` - 插件的元数据引用
///
/// # 返回值
/// * `Self` - 子插件信息实例
///
/// # 提取的字段
/// * `id`: 从 `metadata.id` 提取
/// * `name`: 从 `metadata.name` 提取
/// * `version`: 从 `metadata.version` 提取
/// * `route_prefix`: 从 `metadata.route_prefix` 提取
/// * `is_middle_plugin`: 从 `metadata.is_middle_plugin` 提取
///
/// # 示例
/// ```no_run
/// let child_info = ChildPluginInfo::from_metadata(&plugin_metadata);
/// ```
pub fn from_metadata(metadata: &PluginMetadata) -> Self {
Self {
id: metadata.id.clone(),
name: metadata.name.clone(),
version: metadata.version.clone(),
route_prefix: metadata.route_prefix.clone(),
is_middle_plugin: metadata.is_middle_plugin,
}
}
/// 创建构建器
///
/// 使用构建器模式创建子插件信息,允许链式调用设置各个字段。
///
/// # 返回值
/// * `ChildPluginInfoBuilder` - 子插件信息构建器实例
///
/// # 示例
/// ```no_run
/// let child_info = ChildPluginInfo::builder()
/// .id("child-plugin".to_string())
/// .name("Child Plugin".to_string())
/// .version("1.0.0".to_string())
/// .build()?;
/// ```
pub fn builder() -> ChildPluginInfoBuilder {
ChildPluginInfoBuilder::default()
}
}
/// 子插件信息构建器
#[derive(Default)]
pub struct ChildPluginInfoBuilder {
id: Option<String>,
name: Option<String>,
version: Option<String>,
route_prefix: Option<String>,
is_middle_plugin: bool,
}
impl ChildPluginInfoBuilder {
/// 设置子插件 ID
///
/// 设置子插件的唯一标识符。
///
/// # 参数
/// * `id` - 子插件ID字符串
///
/// # 返回值
/// * `Self` - 返回自身,支持链式调用
pub fn id(mut self, id: String) -> Self {
self.id = Some(id);
self
}
/// 设置子插件名称
///
/// 设置子插件的显示名称。
///
/// # 参数
/// * `name` - 子插件名称字符串
///
/// # 返回值
/// * `Self` - 返回自身,支持链式调用
pub fn name(mut self, name: String) -> Self {
self.name = Some(name);
self
}
/// 设置子插件版本
///
/// 设置子插件的版本号。
///
/// # 参数
/// * `version` - 子插件版本字符串
///
/// # 返回值
/// * `Self` - 返回自身,支持链式调用
pub fn version(mut self, version: String) -> Self {
self.version = Some(version);
self
}
/// 设置路由前缀
///
/// 设置子插件的 HTTP 路由前缀。
///
/// # 参数
/// * `prefix` - 路由前缀字符串
///
/// # 返回值
/// * `Self` - 返回自身,支持链式调用
///
/// # 注意
/// 路由前缀是可选的,如果不设置则使用 `None`。
pub fn route_prefix(mut self, prefix: String) -> Self {
self.route_prefix = Some(prefix);
self
}
/// 设置是否为中间插件
///
/// 设置子插件是否为中间插件。
///
/// # 参数
/// * `is_middle` - 是否为中间插件
///
/// # 返回值
/// * `Self` - 返回自身,支持链式调用
///
/// # 默认值
/// 默认为 `false`。
pub fn is_middle_plugin(mut self, is_middle: bool) -> Self {
self.is_middle_plugin = is_middle;
self
}
/// 构建子插件信息
///
/// 使用构建器中设置的参数创建 `ChildPluginInfo` 实例。
/// 构建过程会验证必填字段。
///
/// # 返回值
/// * `Result<ChildPluginInfo, String>` - 成功时返回子插件信息实例,失败返回错误消息
///
/// # 错误
/// * 如果必填字段(ID、名称、版本)未设置,返回错误
///
/// # 默认值
/// * `route_prefix`: 如果不设置,使用 `None`
/// * `is_middle_plugin`: 默认为 `false`
///
/// # 示例
/// ```no_run
/// let child_info = ChildPluginInfoBuilder::default()
/// .id("child-plugin".to_string())
/// .name("Child Plugin".to_string())
/// .version("1.0.0".to_string())
/// .build()?;
/// ```
pub fn build(self) -> Result<ChildPluginInfo, String> {
Ok(ChildPluginInfo {
id: self.id.ok_or("子插件 ID 不能为空")?,
name: self.name.ok_or("子插件名称不能为空")?,
version: self.version.ok_or("子插件版本不能为空")?,
route_prefix: self.route_prefix,
is_middle_plugin: self.is_middle_plugin,
})
}
}