Skip to main content

mf_macro/
plugin.rs

1/// 传统插件实现宏(旧版)
2/// 用于快速实现 PluginTrait,但缺少元数据支持
3#[macro_export]
4macro_rules! impl_plugin {
5    ($name:ident, $append_fn:expr) => {
6        #[derive(Debug)]
7        pub struct $name {}
8
9        #[async_trait]
10        impl PluginTrait for $name
11        where
12            Self: Send + Sync,
13        {
14            fn metadata(&self) -> PluginMetadata {
15                PluginMetadata {
16                    name: stringify!($name).to_string(),
17                    version: "1.0.0".to_string(),
18                    description: "Auto-generated plugin".to_string(),
19                    author: "Unknown".to_string(),
20                    dependencies: vec![],
21                    conflicts: vec![],
22                    state_fields: vec![],
23                    tags: vec![],
24                }
25            }
26
27            async fn append_transaction(
28                &self,
29                trs: &[Transaction],
30                old_state: &State,
31                new_state: &State,
32            ) -> StateResult<Option<Transaction>> {
33                $append_fn(trs, old_state, new_state).await
34            }
35
36            async fn filter_transaction(
37                &self,
38                _tr: &Transaction,
39                _state: &State,
40            ) -> bool {
41                true
42            }
43        }
44    };
45    ($name:ident, $append_fn:expr, $filter_fn:expr) => {
46        #[derive(Debug)]
47        pub struct $name {}
48
49        #[async_trait]
50        impl PluginTrait for $name
51        where
52            Self: Send + Sync,
53        {
54            fn metadata(&self) -> PluginMetadata {
55                PluginMetadata {
56                    name: stringify!($name).to_string(),
57                    version: "1.0.0".to_string(),
58                    description: "Auto-generated plugin".to_string(),
59                    author: "Unknown".to_string(),
60                    dependencies: vec![],
61                    conflicts: vec![],
62                    state_fields: vec![],
63                    tags: vec![],
64                }
65            }
66
67            async fn append_transaction(
68                &self,
69                trs: &[Transaction],
70                old_state: &State,
71                new_state: &State,
72            ) -> StateResult<Option<Transaction>> {
73                $append_fn(trs, old_state, new_state).await
74            }
75
76            async fn filter_transaction(
77                &self,
78                tr: &Transaction,
79                state: &State,
80            ) -> bool {
81                $filter_fn(tr, state)
82            }
83        }
84    };
85}
86
87/// 创建插件元数据的宏,不需要名称参数(名称将由mf_plugin!宏自动提供)  
88#[macro_export]
89macro_rules! mf_meta {
90    (
91        version = $version:expr
92        $(, description = $desc:expr)?
93        $(, author = $author:expr)?
94        $(, dependencies = [$($dep:expr),* $(,)?])?
95        $(, conflicts = [$($conflict:expr),* $(,)?])?
96        $(, state_fields = [$($field:expr),* $(,)?])?
97        $(, tags = [$($tag:expr),* $(,)?])?
98    ) => {{
99        mf_state::plugin::PluginMetadata {
100            name: "".to_string(),  // 将被mf_plugin!宏替换
101            version: $version.to_string(),
102            description: {
103                #[allow(unused_mut)]
104                let mut desc = "Auto-generated plugin".to_string();
105                $(desc = $desc.to_string();)?
106                desc
107            },
108            author: {
109                #[allow(unused_mut)]
110                let mut author = "Unknown".to_string();
111                $(author = $author.to_string();)?
112                author
113            },
114            dependencies: vec![$($($dep.to_string(),)*)?],
115            conflicts: vec![$($($conflict.to_string(),)*)?],
116            state_fields: vec![$($($field.to_string(),)*)?],
117            tags: vec![$($($tag.to_string(),)*)?],
118        }
119    }};
120}
121
122/// 创建插件元数据的辅助宏 (已废弃,请使用 mf_meta!)
123#[deprecated(
124    since = "2.0.0",
125    note = "请使用 mf_meta! 宏代替,它不需要重复指定插件名称"
126)]
127#[macro_export]
128macro_rules! mf_plugin_metadata {
129    ($name:expr) => {{
130        mf_state::plugin::PluginMetadata {
131            name: $name.to_string(),
132            version: "1.0.0".to_string(),
133            description: "Auto-generated plugin".to_string(),
134            author: "Unknown".to_string(),
135            dependencies: vec![],
136            conflicts: vec![],
137            state_fields: vec![],
138            tags: vec![],
139        }
140    }};
141
142    ($name:expr, version = $version:expr) => {{
143        mf_state::plugin::PluginMetadata {
144            name: $name.to_string(),
145            version: $version.to_string(),
146            description: "Auto-generated plugin".to_string(),
147            author: "Unknown".to_string(),
148            dependencies: vec![],
149            conflicts: vec![],
150            state_fields: vec![],
151            tags: vec![],
152        }
153    }};
154
155    ($name:expr,
156     version = $version:expr,
157     description = $desc:expr,
158     author = $author:expr
159     $(, dependencies = [$($dep:expr),* $(,)?])?
160     $(, conflicts = [$($conflict:expr),* $(,)?])?
161     $(, state_fields = [$($field:expr),* $(,)?])?
162     $(, tags = [$($tag:expr),* $(,)?])?
163    ) => {{
164        mf_state::plugin::PluginMetadata {
165            name: $name.to_string(),
166            version: $version.to_string(),
167            description: $desc.to_string(),
168            author: $author.to_string(),
169            dependencies: vec![$($($dep.to_string(),)*)?],
170            conflicts: vec![$($($conflict.to_string(),)*)?],
171            state_fields: vec![$($($field.to_string(),)*)?],
172            tags: vec![$($($tag.to_string(),)*)?],
173        }
174    }};
175}
176
177/// 创建插件配置的辅助宏
178#[macro_export]
179macro_rules! mf_plugin_config {
180    () => {{
181        mf_state::plugin::PluginConfig {
182            enabled: true,
183            priority: 0,
184            settings: std::collections::HashMap::new(),
185        }
186    }};
187
188    (enabled = $enabled:expr, priority = $priority:expr) => {{
189        mf_state::plugin::PluginConfig {
190            enabled: $enabled,
191            priority: $priority,
192            settings: std::collections::HashMap::new(),
193        }
194    }};
195
196    (enabled = $enabled:expr, priority = $priority:expr, settings = { $($key:expr => $value:expr),* $(,)? }) => {{
197        let mut settings = std::collections::HashMap::new();
198        $(
199            settings.insert($key.to_string(), serde_json::json!($value));
200        )*
201        mf_state::plugin::PluginConfig {
202            enabled: $enabled,
203            priority: $priority,
204            settings,
205        }
206    }};
207}
208
209/// 定义具有声明式语法的 ModuForge 插件,类似于 extension! 宏的设计
210///
211/// # 示例
212///
213/// ```rust
214/// use mf_macro::{mf_plugin, mf_plugin_metadata, mf_plugin_config};
215/// use mf_state::{Transaction, State, plugin::PluginMetadata, plugin::PluginConfig};
216/// use mf_state::error::StateResult;
217///
218/// // 定义事务处理函数
219/// async fn validate_transaction(
220///     _trs: &[Transaction],
221///     _old_state: &State,
222///     _new_state: &State,
223/// ) -> StateResult<Option<Transaction>> {
224///     println!("验证事务");
225///     Ok(None)
226/// }
227///
228/// async fn filter_transaction(tr: &Transaction, _state: &State) -> bool {
229///     // 简单的过滤逻辑
230///     true
231/// }
232///
233/// // 使用声明式语法创建插件
234/// mf_plugin!(
235///     validation_plugin,
236///     metadata = mf_plugin_metadata!(
237///         "validation_plugin",
238///         version = "1.0.0",
239///         description = "事务验证插件",
240///         author = "ModuForge Team",
241///         tags = ["validation", "security"]
242///     ),
243///     config = mf_plugin_config!(
244///         enabled = true,
245///         priority = 10,
246///         settings = { "strict_mode" => true, "timeout" => 5000 }
247///     ),
248///     append_transaction = validate_transaction,
249///     filter_transaction = filter_transaction,
250///     docs = "用于事务验证和安全检查的插件"
251/// );
252///
253/// // 使用方法
254/// let plugin = validation_plugin::new();
255/// let spec = validation_plugin::spec();
256/// ```
257#[macro_export]
258macro_rules! mf_plugin {
259    (
260        $name:ident
261        $(, metadata = $metadata:expr)?
262        $(, config = $config:expr)?
263        $(, append_transaction = $append_fn:expr)?
264        $(, filter_transaction = $filter_fn:expr)?
265        $(, state_field = $state_field:expr)?
266        $(, docs = $docs:expr)?
267        $(,)?
268    ) => {
269        $( #[doc = $docs] )?
270        ///
271        /// 用于框架的 ModuForge 插件。
272        /// 要使用它,请调用 new() 方法获取插件实例或 spec() 方法获取插件规范:
273        ///
274        /// ```rust,ignore
275        /// use mf_state::plugin::{Plugin, PluginSpec};
276        ///
277        #[doc = concat!("let plugin = ", stringify!($name), "::new();")]
278        #[doc = concat!("let spec = ", stringify!($name), "::spec();")]
279        /// ```
280        #[allow(non_camel_case_types)]
281        #[derive(Debug)]
282        pub struct $name;
283
284        impl $name {
285            /// 创建插件实例
286            pub fn new() -> mf_state::plugin::Plugin {
287                let spec = Self::spec();
288                mf_state::plugin::Plugin::new(spec)
289            }
290
291            /// 获取插件规范
292            pub fn spec() -> mf_state::plugin::PluginSpec {
293                let trait_impl = std::sync::Arc::new(Self);
294                mf_state::plugin::PluginSpec {
295                    state_field: {
296                        #[allow(unused_mut)]
297                        let mut field: Option<std::sync::Arc<dyn mf_state::plugin::ErasedStateField>> = None;
298                        $(
299                            field = Some(std::sync::Arc::new($state_field) as std::sync::Arc<dyn mf_state::plugin::ErasedStateField>);
300                        )?
301                        field
302                    },
303                    tr: trait_impl,
304                }
305            }
306        }
307
308        #[async_trait::async_trait]
309        impl mf_state::plugin::PluginTrait for $name {
310            fn metadata(&self) -> mf_state::plugin::PluginMetadata {
311                #[allow(unreachable_code)]
312                {
313                    $(
314                        let mut metadata = $metadata;
315                        metadata.name = stringify!($name).to_string();
316                        return metadata;
317                    )?
318                    mf_state::plugin::PluginMetadata {
319                        name: stringify!($name).to_string(),
320                        version: "1.0.0".to_string(),
321                        description: "Auto-generated plugin".to_string(),
322                        author: "Unknown".to_string(),
323                        dependencies: vec![],
324                        conflicts: vec![],
325                        state_fields: vec![],
326                        tags: vec![],
327                    }
328                }
329            }
330
331            $(
332                fn config(&self) -> mf_state::plugin::PluginConfig {
333                    $config
334                }
335            )?
336
337            $(
338                async fn append_transaction(
339                    &self,
340                    trs: &[std::sync::Arc<mf_state::transaction::Transaction>],
341                    old_state: &std::sync::Arc<mf_state::state::State>,
342                    new_state: &std::sync::Arc<mf_state::state::State>,
343                ) -> mf_state::error::StateResult<Option<mf_state::transaction::Transaction>> {
344                    ($append_fn)(trs, old_state, new_state).await
345                }
346            )?
347
348            $(
349                async fn filter_transaction(
350                    &self,
351                    tr: &mf_state::transaction::Transaction,
352                    state: &mf_state::state::State,
353                ) -> bool {
354                    ($filter_fn)(tr, state).await
355                }
356            )?
357        }
358
359    };
360}
361
362/// 带配置支持的可配置插件宏
363#[macro_export]
364macro_rules! mf_plugin_with_config {
365    (
366        $name:ident,
367        config = { $( $config_field:ident : $config_type:ty ),+ $(,)? },
368        init_fn = $init_fn:expr
369        $(, docs = $docs:expr )?
370        $(,)?
371    ) => {
372        $( #[doc = $docs] )?
373        ///
374        /// 可配置的 ModuForge 插件。
375        #[allow(non_camel_case_types)]
376        #[derive(Debug)]
377        pub struct $name;
378
379        impl $name {
380            /// 使用配置创建插件实例
381            pub fn new( $( $config_field: $config_type ),+ ) -> mf_state::plugin::Plugin {
382                let spec = Self::spec($( $config_field ),+);
383                mf_state::plugin::Plugin::new(spec)
384            }
385
386            /// 使用配置获取插件规范
387            pub fn spec( $( $config_field: $config_type ),+ ) -> mf_state::plugin::PluginSpec {
388                ($init_fn)($( $config_field ),+)
389            }
390        }
391    };
392}
393
394#[macro_export]
395macro_rules! derive_plugin_state {
396    ($name:ident) => {
397        impl Resource for $name {}
398    };
399}