Skip to main content

pipedash_plugin_api/
delegate.rs

1#[macro_export]
2macro_rules! plugin_struct {
3    ($name:ident, $client:ty, $meta:expr $(; $($field:ident: $fty:ty = $init:expr),+ $(,)?)?) => {
4        $crate::plugin_struct!(@define $name, $meta;
5            client: Option<$client> = None,
6            config: ::std::collections::HashMap<String, String> = ::std::collections::HashMap::new()
7            $(, $($field: $fty = $init),+)?
8        );
9
10        impl $name {
11            fn client(&self) -> $crate::PluginResult<&$client> {
12                self.client.as_ref().ok_or_else(|| {
13                    $crate::PluginError::Internal("Plugin not initialized".to_string())
14                })
15            }
16        }
17    };
18    (custom $name:ident, $meta:expr; $($field:ident: $fty:ty = $init:expr),+ $(,)?) => {
19        $crate::plugin_struct!(@define $name, $meta; $($field: $fty = $init),+);
20    };
21    (@define $name:ident, $meta:expr; $($field:ident: $fty:ty = $init:expr),*) => {
22        pub struct $name {
23            metadata: $crate::PluginMetadata,
24            $($field: $fty,)*
25        }
26
27        impl Default for $name {
28            fn default() -> Self {
29                Self::new()
30            }
31        }
32
33        impl $name {
34            pub fn new() -> Self {
35                Self {
36                    metadata: $meta,
37                    $($field: $init,)*
38                }
39            }
40        }
41    };
42}
43
44#[macro_export]
45macro_rules! plugin_impl {
46    ($ty:ident [$($methods:tt)*] { $($items:tt)* }) => {
47        $crate::plugin_impl!(@munch $ty { $($items)* } [$($methods)*] []);
48    };
49    (@munch $ty:ident { $($items:tt)* } [] [$($out:tt)*]) => {
50        #[::async_trait::async_trait]
51        impl $crate::Plugin for $ty {
52            $($items)*
53            $($out)*
54        }
55    };
56    (@munch $ty:ident $items:tt [metadata $(, $($rest:tt)*)?] [$($out:tt)*]) => {
57        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
58            fn metadata(&self) -> &$crate::PluginMetadata {
59                &self.metadata
60            }
61        ]);
62    };
63    (@munch $ty:ident $items:tt [status_source $(, $($rest:tt)*)?] [$($out:tt)*]) => {
64        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
65            fn status_source(&self) -> Option<&$crate::StatusSource> {
66                self.status_source.as_ref()
67            }
68        ]);
69    };
70    (@munch $ty:ident $items:tt [available_from_filtered $(, $($rest:tt)*)?] [$($out:tt)*]) => {
71        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
72            async fn fetch_available_pipelines(
73                &self, params: Option<$crate::PaginationParams>,
74            ) -> $crate::PluginResult<$crate::PaginatedAvailablePipelines> {
75                self.fetch_available_pipelines_filtered(None, None, params).await
76            }
77        ]);
78    };
79    (@munch $ty:ident $items:tt [fetch_available_pipelines $(, $($rest:tt)*)?] [$($out:tt)*]) => {
80        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
81            async fn fetch_available_pipelines(
82                &self, params: Option<$crate::PaginationParams>,
83            ) -> $crate::PluginResult<$crate::PaginatedAvailablePipelines> {
84                self.fetch_available_pipelines_impl(params).await
85            }
86        ]);
87    };
88    (@munch $ty:ident $items:tt [fetch_available_pipelines_filtered $(, $($rest:tt)*)?] [$($out:tt)*]) => {
89        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
90            async fn fetch_available_pipelines_filtered(
91                &self, org: Option<String>, search: Option<String>,
92                params: Option<$crate::PaginationParams>,
93            ) -> $crate::PluginResult<$crate::PaginatedAvailablePipelines> {
94                self.fetch_available_pipelines_filtered_impl(org, search, params).await
95            }
96        ]);
97    };
98    (@munch $ty:ident $items:tt [fetch_organizations $(, $($rest:tt)*)?] [$($out:tt)*]) => {
99        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
100            async fn fetch_organizations(&self) -> $crate::PluginResult<Vec<$crate::Organization>> {
101                self.fetch_organizations_impl().await
102            }
103        ]);
104    };
105    (@munch $ty:ident $items:tt [ids_with_ci $(, $($rest:tt)*)?] [$($out:tt)*]) => {
106        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
107            async fn ids_with_ci(&self, ids: Vec<String>) -> $crate::PluginResult<Vec<String>> {
108                self.ids_with_ci_impl(ids).await
109            }
110        ]);
111    };
112    (@munch $ty:ident $items:tt [fetch_pipelines $(, $($rest:tt)*)?] [$($out:tt)*]) => {
113        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
114            async fn fetch_pipelines(&self) -> $crate::PluginResult<Vec<$crate::Pipeline>> {
115                self.fetch_pipelines_impl().await
116            }
117        ]);
118    };
119    (@munch $ty:ident $items:tt [fetch_run_history $(, $($rest:tt)*)?] [$($out:tt)*]) => {
120        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
121            async fn fetch_run_history(
122                &self, pipeline_id: &str, limit: usize,
123            ) -> $crate::PluginResult<Vec<$crate::PipelineRun>> {
124                self.fetch_run_history_impl(pipeline_id, limit).await
125            }
126        ]);
127    };
128    (@munch $ty:ident $items:tt [fetch_run_details $(, $($rest:tt)*)?] [$($out:tt)*]) => {
129        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
130            async fn fetch_run_details(
131                &self, pipeline_id: &str, run_number: i64,
132            ) -> $crate::PluginResult<$crate::PipelineRun> {
133                self.fetch_run_details_impl(pipeline_id, run_number).await
134            }
135        ]);
136    };
137    (@munch $ty:ident $items:tt [fetch_recent_runs $(, $($rest:tt)*)?] [$($out:tt)*]) => {
138        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
139            async fn fetch_recent_runs(
140                &self, pipeline_ids: &[String], limit: usize,
141            ) -> $crate::PluginResult<
142                ::std::collections::HashMap<String, Vec<$crate::PipelineRun>>,
143            > {
144                self.fetch_recent_runs_impl(pipeline_ids, limit).await
145            }
146        ]);
147    };
148    (@munch $ty:ident $items:tt [fetch_log_nodes $(, $($rest:tt)*)?] [$($out:tt)*]) => {
149        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
150            async fn fetch_log_nodes(
151                &self, run: $crate::RunRef<'_>,
152            ) -> $crate::PluginResult<Vec<$crate::LogNode>> {
153                self.fetch_log_nodes_impl(run).await
154            }
155        ]);
156    };
157    (@munch $ty:ident $items:tt [read_log $(, $($rest:tt)*)?] [$($out:tt)*]) => {
158        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
159            async fn read_log(
160                &self, run: $crate::RunRef<'_>, node_id: &str, from: Option<&$crate::LogCursor>,
161                sink: &mut $crate::LogSink,
162            ) -> $crate::PluginResult<$crate::LogRead> {
163                self.read_log_impl(run, node_id, from, sink).await
164            }
165        ]);
166    };
167    (@munch $ty:ident $items:tt [fetch_workflow_parameters $(, $($rest:tt)*)?] [$($out:tt)*]) => {
168        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
169            async fn fetch_workflow_parameters(
170                &self, workflow_id: &str,
171            ) -> $crate::PluginResult<Vec<$crate::WorkflowParameter>> {
172                self.fetch_workflow_parameters_impl(workflow_id).await
173            }
174        ]);
175    };
176    (@munch $ty:ident $items:tt [trigger_pipeline $(, $($rest:tt)*)?] [$($out:tt)*]) => {
177        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
178            async fn trigger_pipeline(
179                &self, params: $crate::TriggerParams,
180            ) -> $crate::PluginResult<$crate::TriggerResult> {
181                self.trigger_pipeline_impl(params).await
182            }
183        ]);
184    };
185    (@munch $ty:ident $items:tt [cancel_run $(, $($rest:tt)*)?] [$($out:tt)*]) => {
186        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
187            async fn cancel_run(
188                &self, pipeline_id: &str, run_number: i64,
189            ) -> $crate::PluginResult<()> {
190                self.cancel_run_impl(pipeline_id, run_number).await
191            }
192        ]);
193    };
194    (@munch $ty:ident $items:tt [force_cancel_run $(, $($rest:tt)*)?] [$($out:tt)*]) => {
195        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
196            async fn force_cancel_run(
197                &self, pipeline_id: &str, run_number: i64,
198            ) -> $crate::PluginResult<()> {
199                self.force_cancel_run_impl(pipeline_id, run_number).await
200            }
201        ]);
202    };
203    (@munch $ty:ident $items:tt [review_run $(, $($rest:tt)*)?] [$($out:tt)*]) => {
204        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
205            async fn review_run(
206                &self, pipeline_id: &str, run_number: i64, decision: $crate::ReviewDecision,
207            ) -> $crate::PluginResult<()> {
208                self.review_run_impl(pipeline_id, run_number, decision).await
209            }
210        ]);
211    };
212    (@munch $ty:ident $items:tt [rerun_run $(, $($rest:tt)*)?] [$($out:tt)*]) => {
213        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
214            async fn rerun_run(
215                &self, pipeline_id: &str, run_number: i64,
216            ) -> $crate::PluginResult<()> {
217                self.rerun(pipeline_id, run_number, false).await
218            }
219        ]);
220    };
221    (@munch $ty:ident $items:tt [rerun_failed_jobs $(, $($rest:tt)*)?] [$($out:tt)*]) => {
222        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
223            async fn rerun_failed_jobs(
224                &self, pipeline_id: &str, run_number: i64,
225            ) -> $crate::PluginResult<()> {
226                self.rerun(pipeline_id, run_number, true).await
227            }
228        ]);
229    };
230    (@munch $ty:ident $items:tt [enable_pipeline $(, $($rest:tt)*)?] [$($out:tt)*]) => {
231        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
232            async fn enable_pipeline(&self, pipeline_id: &str) -> $crate::PluginResult<()> {
233                self.enable_pipeline_impl(pipeline_id).await
234            }
235        ]);
236    };
237    (@munch $ty:ident $items:tt [check_permissions $(, $($rest:tt)*)?] [$($out:tt)*]) => {
238        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
239            async fn check_permissions(&self) -> $crate::PluginResult<$crate::PermissionStatus> {
240                self.check_permissions_impl().await
241            }
242        ]);
243    };
244    (@munch $ty:ident $items:tt [check_health $(, $($rest:tt)*)?] [$($out:tt)*]) => {
245        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
246            async fn check_health(
247                &self,
248            ) -> $crate::PluginResult<Vec<$crate::ComponentHealth>> {
249                self.check_health_impl().await
250            }
251        ]);
252    };
253    (@munch $ty:ident $items:tt [get_feature_availability $(, $($rest:tt)*)?] [$($out:tt)*]) => {
254        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
255            fn get_feature_availability(
256                &self, status: &$crate::PermissionStatus,
257            ) -> Vec<$crate::FeatureAvailability> {
258                self.get_feature_availability_impl(status)
259            }
260        ]);
261    };
262    (@munch $ty:ident $items:tt [get_field_options $(, $($rest:tt)*)?] [$($out:tt)*]) => {
263        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
264            async fn get_field_options(
265                &self, field_key: &str, config: &::std::collections::HashMap<String, String>,
266            ) -> $crate::PluginResult<Vec<String>> {
267                self.get_field_options_impl(field_key, config).await
268            }
269        ]);
270    };
271}
272
273#[cfg(test)]
274mod tests;