unistore_core/capability.rs
1//! Capability trait 定义
2//!
3//! 所有能力模块必须实现此 trait,它是能力层的核心契约。
4
5use async_trait::async_trait;
6
7use crate::error::CapabilityError;
8use crate::info::CapabilityInfo;
9
10/// 能力 trait - 所有扩展能力的共同契约
11///
12/// 每个能力模块(如 serial、http、sqlite)都必须实现此 trait。
13/// 它定义了能力的生命周期、元数据和健康检查接口。
14///
15/// # 生命周期
16///
17/// ```text
18/// ┌───────────────────────────────────────────────────────────┐
19/// │ Created ──► start() ──► Running ──► stop() ──► Stopped │
20/// │ │ │ │
21/// │ ▼ ▼ │
22/// │ StartError StopError │
23/// └───────────────────────────────────────────────────────────┘
24/// ```
25///
26/// # 实现示例
27///
28/// ```ignore
29/// use unistore_core::{Capability, CapabilityInfo, CapabilityError};
30/// use async_trait::async_trait;
31///
32/// pub struct SerialCapability {
33/// config: SerialConfig,
34/// }
35///
36/// #[async_trait]
37/// impl Capability for SerialCapability {
38/// fn info(&self) -> CapabilityInfo {
39/// CapabilityInfo::new("serial", env!("CARGO_PKG_VERSION"))
40/// .with_description("Serial port communication capability")
41/// }
42///
43/// async fn start(&mut self) -> Result<(), CapabilityError> {
44/// // 初始化串口资源
45/// Ok(())
46/// }
47///
48/// async fn stop(&mut self) -> Result<(), CapabilityError> {
49/// // 关闭所有串口连接
50/// Ok(())
51/// }
52///
53/// async fn health_check(&self) -> Result<(), CapabilityError> {
54/// // 检查能力状态
55/// Ok(())
56/// }
57/// }
58/// ```
59#[async_trait]
60pub trait Capability: Send + Sync {
61 /// 获取能力的元数据信息
62 ///
63 /// 返回能力的名称、版本、描述等信息。
64 /// 此方法应该是纯函数,不应有副作用。
65 fn info(&self) -> CapabilityInfo;
66
67 /// 启动能力
68 ///
69 /// 在此方法中初始化能力所需的资源,如:
70 /// - 建立连接
71 /// - 启动后台任务
72 /// - 加载配置
73 ///
74 /// # 错误
75 ///
76 /// 如果初始化失败,返回 `CapabilityError::StartFailed`。
77 async fn start(&mut self) -> Result<(), CapabilityError>;
78
79 /// 停止能力
80 ///
81 /// 在此方法中清理能力占用的资源,如:
82 /// - 关闭连接
83 /// - 取消后台任务
84 /// - 刷新缓冲区
85 ///
86 /// # 错误
87 ///
88 /// 如果清理失败,返回 `CapabilityError::StopFailed`。
89 /// 即使返回错误,运行时也会继续停止其他能力。
90 async fn stop(&mut self) -> Result<(), CapabilityError>;
91
92 /// 健康检查
93 ///
94 /// 检查能力是否正常工作。默认实现返回 Ok。
95 ///
96 /// # 用途
97 ///
98 /// - 运行时定期调用,检测能力健康状态
99 /// - 用于负载均衡和故障转移决策
100 ///
101 /// # 错误
102 ///
103 /// 如果能力不健康,返回 `CapabilityError::Unhealthy`。
104 async fn health_check(&self) -> Result<(), CapabilityError> {
105 Ok(())
106 }
107
108 /// 能力是否支持热重载
109 ///
110 /// 如果返回 `true`,运行时可以在不停止其他能力的情况下
111 /// 重新加载此能力的配置或实现。
112 ///
113 /// 默认返回 `false`。
114 fn supports_hot_reload(&self) -> bool {
115 false
116 }
117
118 /// 能力的依赖列表
119 ///
120 /// 返回此能力依赖的其他能力名称列表。
121 /// 运行时会确保依赖的能力先于此能力启动。
122 ///
123 /// 默认返回空列表(无依赖)。
124 fn dependencies(&self) -> Vec<&'static str> {
125 vec![]
126 }
127}
128
129/// 类型擦除的能力盒子
130///
131/// 用于在运行时存储和管理不同类型的能力实例。
132pub type BoxedCapability = Box<dyn Capability>;
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137
138 struct TestCapability {
139 started: bool,
140 }
141
142 #[async_trait]
143 impl Capability for TestCapability {
144 fn info(&self) -> CapabilityInfo {
145 CapabilityInfo::new("test", "0.1.0")
146 }
147
148 async fn start(&mut self) -> Result<(), CapabilityError> {
149 self.started = true;
150 Ok(())
151 }
152
153 async fn stop(&mut self) -> Result<(), CapabilityError> {
154 self.started = false;
155 Ok(())
156 }
157 }
158
159 #[tokio::test]
160 async fn test_capability_lifecycle() {
161 let mut cap = TestCapability { started: false };
162 assert!(!cap.started);
163
164 cap.start().await.unwrap();
165 assert!(cap.started);
166
167 cap.stop().await.unwrap();
168 assert!(!cap.started);
169 }
170}