Skip to main content

txtx_addon_kit/
macros.rs

1#[macro_export]
2macro_rules! diagnosed_error {
3    ($($arg:tt)*) => {{
4        use txtx_addon_kit::types::diagnostics::{DiagnosticLevel, Diagnostic};
5
6        let res = format_args!($($arg)*).to_string();
7        Diagnostic::error_from_string(res)
8    }};
9}
10
11#[macro_export]
12macro_rules! define_function {
13    ($func_key:ident => {
14        name: $fn_name:expr,
15        documentation: $doc:expr,
16        example: $example:expr,
17        inputs: [$($input_name:ident: { documentation: $input_doc:expr, typing: $input_ts:expr $(, optional: $input_opt:expr)? }),*],
18        output: { documentation: $output_doc:expr, typing: $output_ts:expr },
19    }) => {
20        txtx_addon_kit::types::functions::FunctionSpecification {
21            name: String::from($fn_name),
22            documentation: String::from($doc),
23            inputs: vec![$(txtx_addon_kit::types::functions::FunctionInput {
24                name: String::from(stringify!($input_name)),
25                documentation: String::from($input_doc),
26                typing: $input_ts,
27                optional: {
28                    let mut is_optional = true;
29                    $(
30                        is_optional = $input_opt;
31                    )?
32                    is_optional
33                },
34            }),*],
35            output: txtx_addon_kit::types::functions::FunctionOutput {
36                documentation: String::from($output_doc),
37                typing: $output_ts,
38            },
39            example: String::from($example),
40            snippet: String::from(""),
41            runner: $func_key::run,
42            checker: $func_key::check_instantiability,
43        };
44    };
45}
46
47#[macro_export]
48macro_rules! define_command {
49    ($func_key:ident => {
50        name: $fn_name:expr,
51        matcher: $matcher:expr,
52        documentation: $doc:expr,
53        implements_signing_capability: $implements_signing_capability:expr,
54        implements_background_task_capability: $implements_background_task_capability:expr,
55        // todo: add key field and use the input_name as the key, so the user can also provide a web-ui facing name
56        inputs: [$($input_name:ident: { documentation: $input_doc:expr, typing: $input_ts:expr, optional: $optional:expr, tainting: $tainting:expr, internal: $internal:expr $(, sensitive: $sensitive:expr)? }),*],
57        outputs: [$($output_name:ident: { documentation: $output_doc:expr, typing: $output_ts:expr }),*],
58        example: $example:expr,
59        $(, implements_cloud_service: $implements_cloud_service:expr)?
60    }) => {
61        {
62        use txtx_addon_kit::types::commands::{PreCommandSpecification, CommandSpecification, CommandInput, CommandOutput, CommandExecutionClosure};
63        let implements_signing_capability: bool = $implements_signing_capability;
64        let implements_background_task_capability: bool = $implements_background_task_capability;
65        PreCommandSpecification::Atomic(
66          CommandSpecification {
67            name: String::from($fn_name),
68            matcher: String::from($matcher),
69            documentation: String::from($doc),
70            accepts_arbitrary_inputs: false,
71            create_output_for_each_input: false,
72            update_addon_defaults: false,
73            create_critical_output: None,
74            implements_signing_capability,
75            implements_background_task_capability,
76            inputs: vec![$(CommandInput {
77                name: String::from(stringify!($input_name)),
78                documentation: String::from($input_doc),
79                typing: $input_ts,
80                optional: $optional,
81                tainting: $tainting,
82                internal: $internal,
83                check_required: false,
84                check_performed: false,
85                sensitive: {
86                    let mut is_sensitive = false;
87                    $(
88                        is_sensitive = $sensitive;
89                    )?
90                    is_sensitive
91                },
92                self_referencing: false
93            }),*],
94            default_inputs: CommandSpecification::default_inputs(),
95            outputs: vec![$(CommandOutput {
96                name: String::from(stringify!($output_name)),
97                documentation: String::from($output_doc),
98                typing: $output_ts,
99            }),*],
100            inputs_post_processing_closure: $func_key::post_process_evaluated_inputs,
101            evaluate_pre_conditions: $func_key::evaluate_pre_conditions,
102            prepare_nested_execution: $func_key::prepare_nested_execution,
103            check_instantiability: $func_key::check_instantiability,
104            check_executability: $func_key::check_executability,
105            run_execution: Box::new($func_key::run_execution),
106            check_signed_executability: $func_key::check_signed_executability,
107            prepare_signed_nested_execution: $func_key::prepare_signed_nested_execution,
108            run_signed_execution: Box::new($func_key::run_signed_execution),
109            build_background_task: Box::new($func_key::build_background_task),
110            implements_cloud_service: {
111                let mut implements_cloud_service = false;
112                $(
113                    implements_cloud_service = $implements_cloud_service;
114                )?
115                implements_cloud_service
116            },
117            aggregate_nested_execution_results: $func_key::aggregate_nested_execution_results,
118            evaluate_post_conditions: $func_key::evaluate_post_conditions,
119            example: String::from($example),
120        }
121      )
122    }
123    };
124}
125
126#[macro_export]
127macro_rules! define_multistep_command {
128  ($func_key:ident => {
129      name: $fn_name:expr,
130      matcher: $matcher:expr,
131      documentation: $doc:expr,
132      parts: [$($part:expr),*],
133      example: $example:expr,
134  }) => {
135      {
136          use txtx_addon_kit::types::commands::{PreCommandSpecification, CompositeCommandSpecification, CommandInput, CommandOutput, CommandExecutionClosure};
137
138          let mut parts = Vec::new();
139          $(parts.push($part);)*
140
141          PreCommandSpecification::Composite( CompositeCommandSpecification {
142              name: String::from($fn_name),
143              matcher: String::from($matcher),
144              documentation: String::from($doc),
145              parts: parts,
146              default_inputs: CommandSpecification::default_inputs(),
147              router: $func_key::router,
148              example: String::from($example),
149          })
150      }
151  };
152}
153
154#[macro_export]
155macro_rules! define_strict_object_type {
156    [
157        $($input_name:ident: {
158            documentation: $input_doc:expr,
159            typing: $input_ts:expr,
160            optional: $optional:expr,
161            tainting: $tainting:expr
162        }),*
163    ] => {
164        Type::strict_object(vec![$(txtx_addon_kit::types::types::ObjectProperty {
165            name: String::from(stringify!($input_name)),
166            documentation: String::from($input_doc),
167            typing: $input_ts,
168            optional: $optional,
169            tainting: $tainting,
170            internal: false,
171        }),*])
172    };
173}
174
175#[macro_export]
176macro_rules! define_documented_arbitrary_object_type {
177    [
178        $($input_name:ident: {
179            documentation: $input_doc:expr,
180            typing: $input_ts:expr,
181            optional: $optional:expr,
182            tainting: $tainting:expr
183        }),*
184    ] => {
185        Type::documented_arbitrary_object(vec![$(txtx_addon_kit::types::types::ObjectProperty {
186            name: String::from(stringify!($input_name)),
187            documentation: String::from($input_doc),
188            typing: $input_ts,
189            optional: $optional,
190            tainting: $tainting,
191            internal: false,
192        }),*])
193    };
194}
195
196#[macro_export]
197macro_rules! define_strict_map_type {
198    [
199        $($input_name:ident: {
200            documentation: $input_doc:expr,
201            typing: $input_ts:expr,
202            optional: $optional:expr,
203            tainting: $tainting:expr
204        }),*
205    ] => {
206        Type::strict_map(vec![$(txtx_addon_kit::types::types::ObjectProperty {
207            name: String::from(stringify!($input_name)),
208            documentation: String::from($input_doc),
209            typing: $input_ts,
210            optional: $optional,
211            tainting: $tainting,
212            internal: false,
213        }),*])
214    };
215}
216
217#[macro_export]
218macro_rules! define_documented_arbitrary_map_type {
219    [
220        $($input_name:ident: {
221            documentation: $input_doc:expr,
222            typing: $input_ts:expr,
223            optional: $optional:expr,
224            tainting: $tainting:expr
225        }),*
226    ] => {
227        Type::documented_arbitrary_map(vec![$(txtx_addon_kit::types::types::ObjectProperty {
228            name: String::from(stringify!($input_name)),
229            documentation: String::from($input_doc),
230            typing: $input_ts,
231            optional: $optional,
232            tainting: $tainting,
233            internal: false,
234        }),*])
235    };
236}
237
238#[macro_export]
239macro_rules! define_addon_type {
240    ($func_key:ident => {
241        name: $fn_name:expr,
242        documentation: $doc:expr,
243    }) => {
244        txtx_addon_kit::types::types::TypeSpecification {
245            id: String::from($fn_name),
246            documentation: String::from($doc),
247            checker: $func_key::check,
248        };
249    };
250}
251
252#[macro_export]
253macro_rules! define_signer {
254    ($func_key:ident => {
255        name: $fn_name:expr,
256        matcher: $matcher:expr,
257        documentation: $doc:expr,
258        inputs: [$($input_name:ident: { documentation: $input_doc:expr, typing: $input_ts:expr, optional: $optional:expr, tainting: $tainting:expr, sensitive: $sensitive:expr }),*],
259        outputs: [$($output_name:ident: { documentation: $output_doc:expr, typing: $output_ts:expr }),*],
260        example: $example:expr
261        $(, force_sequential_signing: $force_sequential_signing:expr)?
262    }) => {
263        {
264          use txtx_addon_kit::types::signers::{SignerSpecification, SignerSignClosure};
265          use txtx_addon_kit::types::commands::{CommandInput, CommandOutput};
266            SignerSpecification {
267                name: String::from($fn_name),
268                matcher: String::from($matcher),
269                documentation: String::from($doc),
270                requires_interaction: false,
271                inputs: vec![$(CommandInput {
272                    name: String::from(stringify!($input_name)),
273                    documentation: String::from($input_doc),
274                    typing: $input_ts,
275                    optional: $optional,
276                    tainting: $tainting,
277                    sensitive: $sensitive,
278                    check_required: false,
279                    check_performed: false,
280                    internal: false,
281                    self_referencing: false,
282                }),*],
283                default_inputs: CommandSpecification::default_inputs(),
284                outputs: vec![$(CommandOutput {
285                    name: String::from(stringify!($output_name)),
286                    documentation: String::from($output_doc),
287                    typing: $output_ts,
288                }),*],
289                check_instantiability: $func_key::check_instantiability,
290                check_activability: $func_key::check_activability,
291                activate: Box::new($func_key::activate),
292                check_signability: $func_key::check_signability,
293                sign: Box::new($func_key::sign),
294                example: String::from($example),
295                force_sequential_signing: false $(|| $force_sequential_signing)?
296            }
297        }
298    };
299}