mf_state/plugin/
plugin.rs

1use async_trait::async_trait;
2use std::sync::Arc;
3
4use crate::error::StateResult;
5use crate::plugin::{PluginConfig, PluginMetadata};
6use crate::resource::Resource;
7
8use crate::state::{State, StateConfig};
9use crate::transaction::Transaction;
10
11/// 插件特征
12/// 定义插件的核心行为,包括事务处理和过滤功能
13#[async_trait]
14pub trait PluginTrait: Send + Sync + Debug {
15    /// 获取插件元数据(静态信息)- 提供默认实现
16    fn metadata(&self) -> PluginMetadata;
17
18    /// 获取插件配置(静态配置)- 提供默认实现
19    fn config(&self) -> PluginConfig {
20        PluginConfig {
21            enabled: true,
22            priority: 0,
23            settings: std::collections::HashMap::new(),
24        }
25    }
26
27    /// 追加事务处理
28    /// 允许插件在事务执行前修改或扩展事务内容
29    async fn append_transaction(
30        &self,
31        _: &[Arc<Transaction>],
32        _: &Arc<State>,
33        _: &Arc<State>,
34    ) -> StateResult<Option<Transaction>> {
35        Ok(None)
36    }
37    /// 事务过滤
38    /// 决定是否允许事务执行
39    async fn filter_transaction(
40        &self,
41        _: &Transaction,
42        _: &State,
43    ) -> bool {
44        true
45    }
46}
47///PluginTrait实现一个 default 实现
48/// 状态字段特征
49/// 使用关联类型保持类型信息,提供类型安全的插件状态管理
50///
51/// # 优势
52/// - ✅ 编译期类型检查,无需运行时 downcast
53/// - ✅ 更好的性能和代码可读性
54/// - ✅ IDE 支持更好的自动补全
55///
56/// # 示例
57///
58/// ```ignore
59/// #[derive(Debug)]
60/// struct MyValue {
61///     count: u32,
62/// }
63/// impl Resource for MyValue {}
64///
65/// #[derive(Debug)]
66/// struct MyStateField;
67///
68/// #[async_trait]
69/// impl StateField for MyStateField {
70///     type Value = MyValue;
71///
72///     async fn init(&self, _config: &StateConfig, _state: &State) -> Arc<MyValue> {
73///         Arc::new(MyValue { count: 0 })
74///     }
75///
76///     async fn apply(&self, _tr: &Transaction, value: Arc<MyValue>,
77///                   _old: &State, _new: &State) -> Arc<MyValue> {
78///         // ✅ 类型安全,无需 downcast
79///         Arc::new(MyValue { count: value.count + 1 })
80///     }
81/// }
82/// ```
83#[async_trait]
84pub trait StateField: Send + Sync + Debug {
85    /// 状态值类型,必须实现 Resource trait
86    type Value: Resource;
87
88    /// 初始化插件状态
89    async fn init(
90        &self,
91        config: &StateConfig,
92        instance: &State,
93    ) -> Arc<Self::Value>;
94
95    /// 应用状态变更
96    /// 根据事务内容更新插件状态
97    async fn apply(
98        &self,
99        tr: &Transaction,
100        value: Arc<Self::Value>,
101        old_state: &State,
102        new_state: &State,
103    ) -> Arc<Self::Value>;
104
105    /// 序列化插件状态(可选)
106    fn serialize(
107        &self,
108        _value: &Arc<Self::Value>,
109    ) -> Option<Vec<u8>> {
110        None
111    }
112
113    /// 反序列化插件状态(可选)
114    fn deserialize(
115        &self,
116        _data: &[u8],
117    ) -> Option<Arc<Self::Value>> {
118        None
119    }
120}
121
122/// 类型擦除的 StateField trait
123/// 用于在 PluginSpec 中存储不同类型的 StateField
124#[async_trait]
125pub trait ErasedStateField: Send + Sync + Debug {
126    /// 初始化插件状态
127    async fn init_erased(
128        &self,
129        config: &StateConfig,
130        instance: &State,
131    ) -> Arc<dyn Resource>;
132
133    /// 应用状态变更
134    async fn apply_erased(
135        &self,
136        tr: &Transaction,
137        value: Arc<dyn Resource>,
138        old_state: &State,
139        new_state: &State,
140    ) -> Arc<dyn Resource>;
141
142    /// 序列化插件状态
143    fn serialize_erased(
144        &self,
145        value: Arc<dyn Resource>,
146    ) -> Option<Vec<u8>>;
147
148    /// 反序列化插件状态
149    fn deserialize_erased(
150        &self,
151        data: &[u8],
152    ) -> Option<Arc<dyn Resource>>;
153}
154
155/// StateField 到 ErasedStateField 的自动实现
156#[async_trait]
157impl<T: StateField + 'static> ErasedStateField for T {
158    #[cfg_attr(feature = "dev-tracing", tracing::instrument(skip(self, config, instance), fields(
159        crate_name = "state",
160        state_field_type = std::any::type_name::<T>(),
161        value_type = std::any::type_name::<T::Value>()
162    )))]
163    async fn init_erased(
164        &self,
165        config: &StateConfig,
166        instance: &State,
167    ) -> Arc<dyn Resource> {
168        let value = self.init(config, instance).await;
169        value as Arc<dyn Resource>
170    }
171
172    #[cfg_attr(feature = "dev-tracing", tracing::instrument(skip(self, tr, value, old_state, new_state), fields(
173        crate_name = "state",
174        state_field_type = std::any::type_name::<T>(),
175        value_type = std::any::type_name::<T::Value>(),
176        tr_id = %tr.id
177    )))]
178    async fn apply_erased(
179        &self,
180        tr: &Transaction,
181        value: Arc<dyn Resource>,
182        old_state: &State,
183        new_state: &State,
184    ) -> Arc<dyn Resource> {
185        // 尝试向下转型到具体类型
186        if let Some(typed_value) = value.downcast_arc::<T::Value>() {
187            let new_value =
188                self.apply(tr, typed_value.clone(), old_state, new_state).await;
189            new_value as Arc<dyn Resource>
190        } else {
191            // 类型不匹配,记录警告并返回原值
192            tracing::warn!(
193                "StateField 类型不匹配,期望 {},跳过应用",
194                std::any::type_name::<T::Value>()
195            );
196            value
197        }
198    }
199
200    #[cfg_attr(feature = "dev-tracing", tracing::instrument(skip(self, value), fields(
201        crate_name = "state",
202        state_field_type = std::any::type_name::<T>(),
203        value_type = std::any::type_name::<T::Value>()
204    )))]
205    fn serialize_erased(
206        &self,
207        value: Arc<dyn Resource>,
208    ) -> Option<Vec<u8>> {
209        if let Some(typed_value) = value.downcast_arc::<T::Value>() {
210            let result = self.serialize(typed_value);
211            #[cfg(feature = "dev-tracing")]
212            if let Some(ref data) = result {
213                tracing::debug!(serialized_size = data.len(), "序列化成功");
214            }
215            result
216        } else {
217            None
218        }
219    }
220
221    #[cfg_attr(feature = "dev-tracing", tracing::instrument(skip(self, data), fields(
222        crate_name = "state",
223        state_field_type = std::any::type_name::<T>(),
224        value_type = std::any::type_name::<T::Value>(),
225        data_size = data.len()
226    )))]
227    fn deserialize_erased(
228        &self,
229        data: &[u8],
230    ) -> Option<Arc<dyn Resource>> {
231        let result = self.deserialize(data).map(|v| v as Arc<dyn Resource>);
232        #[cfg(feature = "dev-tracing")]
233        if result.is_some() {
234            tracing::debug!("反序列化成功");
235        }
236        result
237    }
238}
239
240/// 插件规范结构体
241/// 定义插件的配置和行为
242#[derive(Clone, Debug)]
243pub struct PluginSpec {
244    pub state_field: Option<Arc<dyn ErasedStateField>>,
245    pub tr: Arc<dyn PluginTrait>,
246}
247
248// PluginSpec 所有字段满足 Send+Sync 约束(Arc 指针),无需不安全实现
249
250impl PluginSpec {
251    /// 插件状态管理器
252    #[cfg_attr(feature = "dev-tracing", tracing::instrument(skip(self, tr, state), fields(
253        crate_name = "state",
254        plugin_name = %self.tr.metadata().name,
255        tr_id = %tr.id
256    )))]
257    async fn filter_transaction(
258        &self,
259        tr: &Transaction,
260        state: &State,
261    ) -> bool {
262        let filter = &self.tr;
263        let result = filter.filter_transaction(tr, state).await;
264        #[cfg(feature = "dev-tracing")]
265        tracing::debug!(allowed = result, "过滤结果");
266        result
267    }
268    /// 执行事务追加
269    #[cfg_attr(feature = "dev-tracing", tracing::instrument(skip(self, trs, old_state, new_state), fields(
270        crate_name = "state",
271        plugin_name = %self.tr.metadata().name,
272        tr_count = trs.len()
273    )))]
274    async fn append_transaction(
275        &self,
276        trs: &[Arc<Transaction>],
277        old_state: &Arc<State>,
278        new_state: &Arc<State>,
279    ) -> StateResult<Option<Transaction>> {
280        let tr = self.tr.append_transaction(trs, old_state, new_state).await?;
281        if let Some(mut tr) = tr {
282            let _ = tr.commit(); // 在插件系统中,commit 错误可以被忽略
283            #[cfg(feature = "dev-tracing")]
284            tracing::debug!(step_count = tr.steps.len(), "追加事务成功");
285            Ok(Some(tr))
286        } else {
287            #[cfg(feature = "dev-tracing")]
288            tracing::debug!("无需追加事务");
289            Ok(None)
290        }
291    }
292}
293/// 插件实例结构体
294/// 表示一个具体的插件实例
295#[derive(Clone, Debug)]
296pub struct Plugin {
297    pub spec: PluginSpec,
298    pub key: String,
299}
300
301// Plugin 包含的字段满足 Auto Traits
302
303impl Plugin {
304    /// 创建新的插件实例
305    pub fn new(spec: PluginSpec) -> Self {
306        let key = spec.tr.metadata().name.clone();
307
308        Plugin { spec, key }
309    }
310    /// 获取插件名称
311    pub fn get_name(&self) -> &str {
312        &self.key
313    }
314    /// 获取插件元数据
315    pub fn get_metadata(&self) -> PluginMetadata {
316        self.spec.tr.metadata()
317    }
318    /// 获取插件配置
319    pub fn get_config(&self) -> PluginConfig {
320        self.spec.tr.config()
321    }
322
323    /// 从全局状态中获取插件状态
324    pub fn get_state(
325        &self,
326        state: &State,
327    ) -> Option<Arc<dyn Resource>> {
328        state.get_field(&self.key)
329    }
330    /// 应用事务过滤逻辑
331    #[cfg_attr(feature = "dev-tracing", tracing::instrument(skip(self, tr, state), fields(
332        crate_name = "state",
333        plugin_key = %self.key,
334        tr_id = %tr.id
335    )))]
336    pub async fn apply_filter_transaction(
337        &self,
338        tr: &Transaction,
339        state: &State,
340    ) -> bool {
341        self.spec.filter_transaction(tr, state).await
342    }
343
344    /// 应用事务追加逻辑
345    #[cfg_attr(feature = "dev-tracing", tracing::instrument(skip(self, trs, old_state, new_state), fields(
346        crate_name = "state",
347        plugin_key = %self.key,
348        tr_count = trs.len()
349    )))]
350    pub async fn apply_append_transaction(
351        &self,
352        trs: &[Arc<Transaction>],
353        old_state: &Arc<State>,
354        new_state: &Arc<State>,
355    ) -> StateResult<Option<Transaction>> {
356        self.spec.append_transaction(trs, old_state, new_state).await
357    }
358}
359
360/// 插件状态类型
361/// 使用 Arc 包装的任意类型作为插件状态
362//pub type PluginState = Arc<dyn std::any::Any + Send + Sync>;
363use std::fmt::Debug;