Skip to main content

ownable_std_macros/
lib.rs

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