ownable_std_macros/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, AttributeArgs, Data::{Enum, Struct}, DataEnum, DataStruct, DeriveInput, FieldsNamed};
4
5/// adds Transfer { to: Addr } variant to ExecuteMsg
6#[proc_macro_attribute]
7pub fn ownables_transfer(metadata: TokenStream, input: TokenStream) -> TokenStream {
8
9    // validate no input args
10    let meta_ast = parse_macro_input!(metadata as AttributeArgs);
11    if let Some(arg) = meta_ast.first() {
12        return syn::Error::new_spanned(arg, "no args expected")
13            .to_compile_error()
14            .into();
15    }
16
17    // define the variants to be inserted and parse into DataEnum
18    let default_execute_variants: TokenStream = quote! {
19        enum ExecuteMsg {
20            Transfer {to: Addr},
21        }
22    }
23    .into();
24    let default_ast: DeriveInput = parse_macro_input!(default_execute_variants);
25    let default_variants = match default_ast.data {
26        Enum(DataEnum { variants, .. }) => variants,
27        _ => panic!("only enums can provide variants"),
28    };
29
30    // parse the input variants
31    let mut input_ast: DeriveInput = parse_macro_input!(input);
32    let input_variants_data = match &mut input_ast.data {
33        Enum(DataEnum { variants, .. }) => variants,
34        _ => panic!("only enums can accept variants")
35    };
36
37    // insert variants from the default to input
38    input_variants_data.extend(default_variants.into_iter());
39
40    quote! { #input_ast }.into()
41}
42
43/// adds Lock {} variant to ExecuteMsg
44#[proc_macro_attribute]
45pub fn ownables_lock(metadata: TokenStream, input: TokenStream) -> TokenStream {
46
47    // validate no input args
48    let meta_ast = parse_macro_input!(metadata as AttributeArgs);
49    if let Some(arg) = meta_ast.first() {
50        return syn::Error::new_spanned(arg, "no args expected")
51            .to_compile_error()
52            .into();
53    }
54
55    // define the variants to be inserted and parse into DataEnum
56    let default_execute_variants: TokenStream = quote! {
57        enum ExecuteMsg {
58            Lock {},
59        }
60    }
61        .into();
62    let default_ast: DeriveInput = parse_macro_input!(default_execute_variants);
63    let default_variants = match default_ast.data {
64        Enum(DataEnum { variants, .. }) => variants,
65        _ => panic!("only enums can provide variants"),
66    };
67
68    // parse the input variants
69    let mut input_ast: DeriveInput = parse_macro_input!(input);
70    let input_variants_data = match &mut input_ast.data {
71        Enum(DataEnum { variants, .. }) => variants,
72        _ => panic!("only enums can accept variants")
73    };
74
75    // insert variants from the default to input
76    input_variants_data.extend(default_variants.into_iter());
77
78    quote! { #input_ast }.into()
79}
80
81/// adds Consume {} variant to ExecuteMsg
82#[proc_macro_attribute]
83pub fn ownables_consume(metadata: TokenStream, input: TokenStream) -> TokenStream {
84
85    // validate no input args
86    let meta_ast = parse_macro_input!(metadata as AttributeArgs);
87    if let Some(arg) = meta_ast.first() {
88        return syn::Error::new_spanned(arg, "no args expected")
89            .to_compile_error()
90            .into();
91    }
92
93    // define the variants to be inserted and parse into DataEnum
94    let default_execute_variants: TokenStream = quote! {
95        enum ExecuteMsg {
96            Consume {},
97        }
98    }
99        .into();
100    let default_ast: DeriveInput = parse_macro_input!(default_execute_variants);
101    let default_variants = match default_ast.data {
102        Enum(DataEnum { variants, .. }) => variants,
103        _ => panic!("only enums can provide variants"),
104    };
105
106    // parse the input variants
107    let mut input_ast: DeriveInput = parse_macro_input!(input);
108    let input_variants_data = match &mut input_ast.data {
109        Enum(DataEnum { variants, .. }) => variants,
110        _ => panic!("only enums can accept variants")
111    };
112
113    // insert variants from the default to input
114    input_variants_data.extend(default_variants.into_iter());
115
116    quote! { #input_ast }.into()
117}
118
119
120/// adds GetMetadata {} variant to QueryMsg
121#[proc_macro_attribute]
122pub fn ownables_query_metadata(metadata: TokenStream, input: TokenStream) -> TokenStream {
123   
124    // validate no input args
125    let meta_ast = parse_macro_input!(metadata as AttributeArgs);
126    if let Some(arg) = meta_ast.first() {
127        return syn::Error::new_spanned(arg, "no args expected")
128            .to_compile_error()
129            .into();
130    }
131
132    // define the variants to be inserted and parse into DataEnum
133    let default_query_variants: TokenStream = quote! {
134        enum QueryMsg {
135            GetMetadata {},
136        }
137    }
138    .into();
139    let default_ast: DeriveInput = parse_macro_input!(default_query_variants);
140    let default_variants = match default_ast.data {
141        Enum(DataEnum { variants, .. }) => variants,
142        _ => panic!("only enums can provide variants"),
143    };
144
145    // parse the input variants
146    let mut input_ast: DeriveInput = parse_macro_input!(input);
147    let input_variants_data = match &mut input_ast.data {
148        Enum(DataEnum { variants, .. }) => variants,
149        _ => panic!("only enums can accept variants")
150    };
151
152    // insert variants from the default to input
153    input_variants_data.extend(default_variants.into_iter());
154
155    quote! { #input_ast }.into()
156}
157
158/// adds GetInfo {} variant to QueryMsg
159#[proc_macro_attribute]
160pub fn ownables_query_info(metadata: TokenStream, input: TokenStream) -> TokenStream {
161
162    // validate no input args
163    let meta_ast = parse_macro_input!(metadata as AttributeArgs);
164    if let Some(arg) = meta_ast.first() {
165        return syn::Error::new_spanned(arg, "no args expected")
166            .to_compile_error()
167            .into();
168    }
169
170    // define the variants to be inserted and parse into DataEnum
171    let default_query_variants: TokenStream = quote! {
172        enum QueryMsg {
173            GetInfo {},
174        }
175    }
176        .into();
177    let default_ast: DeriveInput = parse_macro_input!(default_query_variants);
178    let default_variants = match default_ast.data {
179        Enum(DataEnum { variants, .. }) => variants,
180        _ => panic!("only enums can provide variants"),
181    };
182
183    // parse the input variants
184    let mut input_ast: DeriveInput = parse_macro_input!(input);
185    let input_variants_data = match &mut input_ast.data {
186        Enum(DataEnum { variants, .. }) => variants,
187        _ => panic!("only enums can accept variants")
188    };
189
190    // insert variants from the default to input
191    input_variants_data.extend(default_variants.into_iter());
192
193    quote! { #input_ast }.into()
194}
195
196/// adds GetWidgetState {} variant to QueryMsg
197#[proc_macro_attribute]
198pub fn ownables_query_widget_state(metadata: TokenStream, input: TokenStream) -> TokenStream {
199
200    // validate no input args
201    let meta_ast = parse_macro_input!(metadata as AttributeArgs);
202    if let Some(arg) = meta_ast.first() {
203        return syn::Error::new_spanned(arg, "no args expected")
204            .to_compile_error()
205            .into();
206    }
207
208    // define the variants to be inserted and parse into DataEnum
209    let default_query_variants: TokenStream = quote! {
210        enum QueryMsg {
211            GetWidgetState {},
212        }
213    }
214        .into();
215    let default_ast: DeriveInput = parse_macro_input!(default_query_variants);
216    let default_variants = match default_ast.data {
217        Enum(DataEnum { variants, .. }) => variants,
218        _ => panic!("only enums can provide variants"),
219    };
220
221    // parse the input variants
222    let mut input_ast: DeriveInput = parse_macro_input!(input);
223    let input_variants_data = match &mut input_ast.data {
224        Enum(DataEnum { variants, .. }) => variants,
225        _ => panic!("only enums can accept variants")
226    };
227
228    // insert variants from the default to input
229    input_variants_data.extend(default_variants.into_iter());
230
231    quote! { #input_ast }.into()
232}
233
234/// adds IsLocked {} variant to QueryMsg
235#[proc_macro_attribute]
236pub fn ownables_query_locked(metadata: TokenStream, input: TokenStream) -> TokenStream {
237
238    // validate no input args
239    let meta_ast = parse_macro_input!(metadata as AttributeArgs);
240    if let Some(arg) = meta_ast.first() {
241        return syn::Error::new_spanned(arg, "no args expected")
242            .to_compile_error()
243            .into();
244    }
245
246    // define the variants to be inserted and parse into DataEnum
247    let default_query_variants: TokenStream = quote! {
248        enum QueryMsg {
249            IsLocked {},
250        }
251    }
252        .into();
253    let default_ast: DeriveInput = parse_macro_input!(default_query_variants);
254    let default_variants = match default_ast.data {
255        Enum(DataEnum { variants, .. }) => variants,
256        _ => panic!("only enums can provide variants"),
257    };
258
259    // parse the input variants
260    let mut input_ast: DeriveInput = parse_macro_input!(input);
261    let input_variants_data = match &mut input_ast.data {
262        Enum(DataEnum { variants, .. }) => variants,
263        _ => panic!("only enums can accept variants")
264    };
265
266    // insert variants from the default to input
267    input_variants_data.extend(default_variants.into_iter());
268
269    quote! { #input_ast }.into()
270}
271
272/// adds IsConsumerOf { issuer: Addr, consumable_type: String, } variant to QueryMsg
273#[proc_macro_attribute]
274pub fn ownables_query_consumer_of(metadata: TokenStream, input: TokenStream) -> TokenStream {
275
276    // validate no input args
277    let meta_ast = parse_macro_input!(metadata as AttributeArgs);
278    if let Some(arg) = meta_ast.first() {
279        return syn::Error::new_spanned(arg, "no args expected")
280            .to_compile_error()
281            .into();
282    }
283
284    // define the variants to be inserted and parse into DataEnum
285    let default_query_variants: TokenStream = quote! {
286        enum QueryMsg {
287            IsConsumerOf {
288                issuer: Addr,
289                consumable_type: String,
290            },
291        }
292    }
293        .into();
294    let default_ast: DeriveInput = parse_macro_input!(default_query_variants);
295    let default_variants = match default_ast.data {
296        Enum(DataEnum { variants, .. }) => variants,
297        _ => panic!("only enums can provide variants"),
298    };
299
300    // parse the input variants
301    let mut input_ast: DeriveInput = parse_macro_input!(input);
302    let input_variants_data = match &mut input_ast.data {
303        Enum(DataEnum { variants, .. }) => variants,
304        _ => panic!("only enums can accept variants")
305    };
306
307    // insert variants from the default to input
308    input_variants_data.extend(default_variants.into_iter());
309
310    quote! { #input_ast }.into()
311}
312
313/// adds the default fields to InstantiateMsg struct:
314/// InstantiateMsg {
315///     pub ownable_id: String,
316///     pub package: String,
317///     pub nft: Option<NFT>,
318///     pub ownable_type: Option<String>,
319///     pub network_id: u8,
320/// }
321#[proc_macro_attribute]
322pub fn ownables_instantiate_msg(metadata: TokenStream, input: TokenStream) -> TokenStream {
323    // validate no input args
324    let meta_ast = parse_macro_input!(metadata as AttributeArgs);
325    if let Some(arg) = meta_ast.first() {
326        return syn::Error::new_spanned(arg, "no args expected")
327            .to_compile_error()
328            .into();
329    }
330
331    // define the fields to be inserted and parse into DataEnum
332    let default_instantiate_fields: TokenStream = quote! {
333        struct InstantiateMsg {
334            pub ownable_id: String,
335            pub package: String,
336            pub nft: Option<NFT>,
337            pub ownable_type: Option<String>,
338            pub network_id: u8,
339        }
340    }
341    .into();
342
343    let default_ast: DeriveInput = parse_macro_input!(default_instantiate_fields);
344    let default_fields = match default_ast.data {
345        Struct(DataStruct { fields, .. }) => fields,
346        _ => panic!("only structs can accept fields"),
347    };
348
349    let mut input_ast: DeriveInput = parse_macro_input!(input);
350    let input_fields_data = match &mut input_ast.data {
351        Struct(DataStruct { fields, .. }) => fields,
352        _ => panic!("only structs can accept fields")
353    };
354
355    // push the default fields onto the input
356    if let syn::Fields::Named(FieldsNamed { named, .. }) = input_fields_data {
357        named.extend(default_fields);
358    }
359
360    quote! { #input_ast }.into()
361}
362
363