1#[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#[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(), 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#[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#[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#[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 #[doc = concat!("let plugin = ", stringify!($name), "::new();")]
278 #[doc = concat!("let spec = ", stringify!($name), "::spec();")]
279 #[allow(non_camel_case_types)]
281 #[derive(Debug)]
282 pub struct $name;
283
284 impl $name {
285 pub fn new() -> mf_state::plugin::Plugin {
287 let spec = Self::spec();
288 mf_state::plugin::Plugin::new(spec)
289 }
290
291 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#[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 #[allow(non_camel_case_types)]
376 #[derive(Debug)]
377 pub struct $name;
378
379 impl $name {
380 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 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}