mockforge_plugin_sdk/
macros.rs

1//! Helper macros for plugin development
2
3/// Export a plugin with boilerplate
4///
5/// This macro generates the necessary WASM exports for your plugin.
6///
7/// # Example
8///
9/// ```rust,no_run
10/// use mockforge_plugin_sdk::prelude::*;
11///
12/// #[derive(Debug)]
13/// pub struct MyPlugin;
14///
15/// #[async_trait]
16/// impl AuthPlugin for MyPlugin {
17///     async fn authenticate(&self, context: &PluginContext, credentials: &AuthCredentials) -> PluginResult<AuthResult> {
18///         Ok(AuthResult::authenticated("user123"))
19///     }
20/// }
21///
22/// export_plugin!(MyPlugin);
23/// ```
24#[macro_export]
25macro_rules! export_plugin {
26    ($plugin_type:ty) => {
27        /// Create plugin instance
28        #[no_mangle]
29        pub extern "C" fn create_plugin() -> *mut std::ffi::c_void {
30            let plugin = Box::new(<$plugin_type>::default());
31            Box::into_raw(plugin) as *mut std::ffi::c_void
32        }
33
34        /// Destroy plugin instance
35        #[no_mangle]
36        pub extern "C" fn destroy_plugin(ptr: *mut std::ffi::c_void) {
37            if !ptr.is_null() {
38                unsafe {
39                    let _ = Box::from_raw(ptr as *mut $plugin_type);
40                }
41            }
42        }
43    };
44}
45
46/// Generate a plugin configuration struct
47///
48/// # Example
49///
50/// ```rust,no_run
51/// use mockforge_plugin_sdk::plugin_config;
52///
53/// plugin_config! {
54///     id = "my-plugin",
55///     version = "1.0.0",
56///     name = "My Plugin",
57///     description = "A custom plugin",
58///     types = ["auth"],
59///     author = {
60///         name = "Your Name",
61///         email = "your.email@example.com",
62///     },
63/// }
64/// ```
65#[macro_export]
66macro_rules! plugin_config {
67    (
68        id = $id:expr,
69        version = $version:expr,
70        name = $name:expr,
71        description = $desc:expr,
72        types = [$($plugin_type:expr),*],
73        author = {
74            name = $author_name:expr,
75            email = $author_email:expr $(,)?
76        } $(,)?
77    ) => {
78        /// Plugin configuration
79        pub fn plugin_config() -> mockforge_plugin_core::PluginManifest {
80            use mockforge_plugin_core::*;
81
82            let info = PluginInfo::new(
83                PluginId::new($id),
84                PluginVersion::parse($version).expect("Invalid version"),
85                $name,
86                $desc,
87                PluginAuthor::new($author_name).with_email($author_email),
88            );
89
90            let mut manifest = PluginManifest::new(info);
91            $(
92                manifest.types.push($plugin_type.to_string());
93            )*
94            manifest
95        }
96    };
97}
98
99/// Quick test macro for plugin functions
100///
101/// # Example
102///
103/// ```rust,no_run
104/// # use mockforge_plugin_sdk::prelude::*;
105/// # async fn test_auth() {
106/// plugin_test! {
107///     test_name: authenticate_valid_user,
108///     plugin: MyAuthPlugin,
109///     input: AuthCredentials::basic("user", "pass"),
110///     assert: |result| {
111///         assert!(result.is_ok());
112///     }
113/// }
114/// # }
115/// ```
116#[macro_export]
117macro_rules! plugin_test {
118    (
119        test_name: $name:ident,
120        plugin: $plugin:ty,
121        input: $input:expr,
122        assert: $assert:expr
123    ) => {
124        #[tokio::test]
125        async fn $name() {
126            let plugin = <$plugin>::default();
127            let context = mockforge_plugin_core::PluginContext::default();
128            let result = plugin.process(&context, $input).await;
129            ($assert)(result);
130        }
131    };
132}
133
134/// Create a mock plugin context for testing
135///
136/// # Example
137///
138/// ```rust,no_run
139/// # use mockforge_plugin_sdk::prelude::*;
140/// let context = mock_context! {
141///     plugin_id: "test-plugin",
142///     request_id: "req-123",
143/// };
144/// ```
145#[macro_export]
146macro_rules! mock_context {
147    (
148        plugin_id: $plugin_id:expr,
149        request_id: $request_id:expr $(,)?
150    ) => {{
151        use mockforge_plugin_core::PluginContext;
152        PluginContext {
153            plugin_id: $plugin_id.to_string(),
154            request_id: $request_id.to_string(),
155            ..Default::default()
156        }
157    }};
158
159    () => {{
160        mockforge_plugin_core::PluginContext::default()
161    }};
162}
163
164#[cfg(test)]
165mod tests {
166
167    #[test]
168    fn test_macro_compilation() {
169        // Just verify macros compile
170        // Test passes if compilation succeeds
171    }
172}