1use proc_macro::TokenStream;
2use quote::{quote, ToTokens};
3use syn::{parse::Parser, parse_macro_input, DeriveInput};
4
5fn merge_variants(left: TokenStream, right: TokenStream) -> TokenStream {
8 use syn::Data::Enum;
9 use syn::DataEnum;
10
11 let mut left: DeriveInput = parse_macro_input!(left);
12 let right: DeriveInput = parse_macro_input!(right);
13
14 if let (
15 Enum(DataEnum { variants, .. }),
16 Enum(DataEnum {
17 variants: to_add, ..
18 }),
19 ) = (&mut left.data, right.data)
20 {
21 variants.extend(to_add);
22
23 quote! { #left }.into()
24 } else {
25 syn::Error::new(left.ident.span(), "variants may only be added for enums")
26 .to_compile_error()
27 .into()
28 }
29}
30
31#[proc_macro_attribute]
32pub fn andr_exec(_args: TokenStream, input: TokenStream) -> TokenStream {
40 #[allow(unused_mut)]
41 let mut merged = merge_variants(
42 input,
43 quote! {
44 enum Right {
45 #[serde(rename="amp_receive")]
46 AMPReceive(::andromeda_std::amp::messages::AMPPkt),
47 Ownership(::andromeda_std::ado_base::ownership::OwnershipMessage),
48 UpdateKernelAddress {
49 address: ::cosmwasm_std::Addr,
50 },
51 UpdateAppContract {
52 address: String,
53 },
54 Permissioning(::andromeda_std::ado_base::permissioning::PermissioningMessage),
55 }
56 }
57 .into(),
58 );
59 #[cfg(feature = "modules")]
60 {
61 merged = merge_variants(
62 merged,
63 quote! {
64 enum Right {
65 RegisterModule {
66 module: ::andromeda_std::ado_base::Module,
67 },
68 DeregisterModule {
69 module_idx: ::cosmwasm_std::Uint64,
70 },
71 AlterModule {
72 module_idx: ::cosmwasm_std::Uint64,
73 module: ::andromeda_std::ado_base::Module,
74 },
75 }
76 }
77 .into(),
78 )
79 }
80 let input = parse_macro_input!(merged);
81 TokenStream::from(andr_exec_derive(input).into_token_stream())
82}
83
84fn andr_exec_derive(input: DeriveInput) -> DeriveInput {
86 use syn::parse_quote;
87
88 match input.data {
89 syn::Data::Enum(_) => parse_quote! {
90 #[derive(::andromeda_std::AsRefStr)]
91 #input
92 },
93 _ => panic!("unions are not supported"),
94 }
95}
96
97#[proc_macro_attribute]
105pub fn andr_instantiate(_args: TokenStream, input: TokenStream) -> TokenStream {
106 let mut ast = parse_macro_input!(input as DeriveInput);
107 match &mut ast.data {
108 syn::Data::Struct(ref mut struct_data) => {
109 if let syn::Fields::Named(fields) = &mut struct_data.fields {
110 fields.named.push(
111 syn::Field::parse_named
112 .parse2(quote! { pub kernel_address: String })
113 .unwrap(),
114 );
115 fields.named.push(
116 syn::Field::parse_named
117 .parse2(quote! { pub owner: Option<String> })
118 .unwrap(),
119 );
120 }
121
122 quote! {
123 #ast
124 }
125 .into()
126 }
127 _ => panic!("Macro only works with structs"),
128 }
129}
130
131#[proc_macro_attribute]
132pub fn andr_instantiate_modules(_args: TokenStream, input: TokenStream) -> TokenStream {
133 let mut ast = parse_macro_input!(input as DeriveInput);
134 match &mut ast.data {
135 syn::Data::Struct(ref mut struct_data) => {
136 if let syn::Fields::Named(fields) = &mut struct_data.fields {
137 fields.named.push(
138 syn::Field::parse_named
139 .parse2(
140 quote! { pub modules: Option<Vec<::andromeda_std::ado_base::Module>> },
141 )
142 .unwrap(),
143 );
144 }
145 quote! {
146 #ast
147 }
148 .into()
149 }
150 _ => panic!("Macro only works with structs"),
151 }
152}
153
154#[proc_macro_attribute]
155pub fn andr_query(_metadata: TokenStream, input: TokenStream) -> TokenStream {
159 #[allow(unused_mut)]
160 let mut merged = merge_variants(
161 input,
162 quote! {
163 enum Right {
164 #[returns(andromeda_std::ado_base::ownership::ContractOwnerResponse)]
165 Owner {},
166 #[returns(andromeda_std::ado_base::ownership::ContractPotentialOwnerResponse)]
167 OwnershipRequest {},
168 #[returns(andromeda_std::ado_base::ado_type::TypeResponse)]
169 Type {},
170 #[returns(andromeda_std::ado_base::kernel_address::KernelAddressResponse)]
171 KernelAddress {},
172 #[returns(andromeda_std::ado_base::app_contract::AppContractResponse)]
173 AppContract {},
174 #[returns(andromeda_std::ado_base::ownership::PublisherResponse)]
175 OriginalPublisher {},
176 #[returns(andromeda_std::ado_base::block_height::BlockHeightResponse)]
177 BlockHeightUponCreation {},
178 #[returns(andromeda_std::ado_base::version::VersionResponse)]
179 Version {},
180 #[returns(Vec<::andromeda_std::ado_base::permissioning::PermissionInfo>)]
181 Permissions { actor: String, limit: Option<u32>, start_after: Option<String> },
182 #[returns(Vec<String>)]
183 PermissionedActions { },
184 }
185 }
186 .into(),
187 );
188
189 #[cfg(feature = "modules")]
190 {
191 merged = merge_variants(
192 merged,
193 quote! {
194 enum Right {
195 #[returns(andromeda_std::ado_base::Module)]
196 Module { id: ::cosmwasm_std::Uint64 },
197 #[returns(Vec<String>)]
198 ModuleIds {},
199 }
200 }
201 .into(),
202 );
203 }
204 #[cfg(feature = "module_hooks")]
205 {
206 merged = merge_variants(
207 merged,
208 quote! {
209 enum Right {
210 #[returns(::cosmwasm_std::Binary)]
211 AndrHook(::andromeda_std::ado_base::hooks::AndromedaHook),
212 }
213 }
214 .into(),
215 );
216 }
217
218 merged
219}