Skip to main content

zerolaunch_plugin_host/
info.rs

1//! 插件展示条目 —— 插件管理页 / CLI 的插件级视图。
2//!
3//! 字段权威是 `PluginMetadata`(第三方取自清单,内置由代码声明);本类型只追加
4//! 运行态三件事:进程状态、启用态、已注册组件 id。构造必须经 `from_metadata`,
5//! 不再允许各处自行拼装,避免同一行数据出现多份字段来源。
6
7use serde::Serialize;
8use zerolaunch_plugin_api::plugin::{PluginKind, PluginMetadata, PluginMode};
9
10use crate::manager::PluginRuntimeState;
11
12/// 插件列表 / 详情共用的插件级条目(跨 IPC 序列化,键名为 camelCase)。
13#[derive(Debug, Clone, Serialize)]
14pub struct PluginInfo {
15    /// 插件 id。序列化键名 `pluginId`。
16    #[serde(rename = "pluginId")]
17    pub plugin_id: String,
18    #[serde(rename = "name")]
19    pub name: String,
20    #[serde(rename = "version")]
21    pub version: String,
22    #[serde(rename = "description")]
23    pub description: String,
24    #[serde(rename = "author")]
25    pub author: String,
26    /// 运行状态:已加载取进程状态,未加载固定为 error。
27    #[serde(rename = "state")]
28    pub state: PluginRuntimeState,
29    /// 是否启用:插件自身 Plugin 组件的启用态;未加载恒为 false。
30    #[serde(rename = "enabled")]
31    pub enabled: bool,
32    /// 插件种类:内置或第三方。
33    #[serde(rename = "kind", default)]
34    pub kind: PluginKind,
35    #[serde(rename = "priority")]
36    pub priority: u32,
37    /// 可卸载(仅磁盘安装的第三方插件)。
38    #[serde(rename = "canUninstall")]
39    pub can_uninstall: bool,
40    /// 可重载(仅磁盘安装的第三方插件)。
41    #[serde(rename = "canReload")]
42    pub can_reload: bool,
43    /// 可查看进程日志(仅第三方插件有子进程)。
44    #[serde(rename = "canViewLogs")]
45    pub can_view_logs: bool,
46    /// 可切换启用态(未加载的第三方插件无组件可写)。
47    #[serde(rename = "canToggle")]
48    pub can_toggle: bool,
49    /// 全局唤醒快捷键(如 "Ctrl+E"),可空。
50    #[serde(rename = "hotkey", default)]
51    pub hotkey: Option<String>,
52    /// 插件显示图标(data URL),可空表示无图标。
53    #[serde(rename = "icon", default)]
54    pub icon: Option<String>,
55    /// 插件形态:inline = 行内插件;panel = 独立插件(唯一权威依据)。
56    #[serde(rename = "mode", default)]
57    pub mode: PluginMode,
58}
59
60impl PluginInfo {
61    /// 由插件元数据投影为展示条目。
62    /// 参数:meta - 插件级元数据(字段唯一来源);state - 进程状态;
63    /// enabled - 插件级启用态(Plugin 组件的启用态;其 id 恒等于插件 id)。
64    /// 返回:IPC 展示条目;能力位由 kind/state 在此统一派生。
65    pub fn from_metadata(meta: &PluginMetadata, state: PluginRuntimeState, enabled: bool) -> Self {
66        let third_party = meta.kind == PluginKind::ThirdParty;
67        let can_toggle = !(third_party && matches!(state, PluginRuntimeState::Error));
68        Self {
69            plugin_id: meta.id.clone(),
70            name: meta.name.clone(),
71            version: meta.version.clone(),
72            description: meta.description.clone(),
73            author: meta.author.clone(),
74            state,
75            enabled,
76            kind: meta.kind,
77            priority: meta.priority,
78            can_uninstall: third_party,
79            can_reload: third_party,
80            can_view_logs: third_party,
81            can_toggle,
82            hotkey: meta.hotkey.clone(),
83            icon: meta.icon.clone(),
84            mode: meta.mode,
85        }
86    }
87}