Repository: CosmWasm/sylvia
Pull request #353 (2024-04-17 12:44:38)

chore: Unify MT proxy methods emit
Cleanup in `Multitest` generation. After removing the support for the `contract` macro on `impl Interface` we can merge some methods as they do not differ this much between `interface` and `contract`.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/CosmWasm/sylvia/pull/353?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=CosmWasm) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 84.76%. Comparing base [(`b4bd4b4`)](https://app.codecov.io/gh/CosmWasm/sylvia/commit/b4bd4b44623a3f1d77a737308274c54495fc21ee?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=CosmWasm) to head [(`60f4dfe`)](https://app.codecov.io/gh/CosmWasm/sylvia/pull/353?dropdown=coverage&src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=CosmWasm).


<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #353      +/-   ##
==========================================
- Coverage   85.23%   84.76%   -0.48%     
==========================================
  Files          37       37              
  Lines        2710     2619      -91     
==========================================
- Hits         2310     2220      -90     
+ Misses        400      399       -1     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/CosmWasm/sylvia/pull/353?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=CosmWasm).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=CosmWasm).


Patch:
diff --git a/sylvia-derive/src/message.rs b/sylvia-derive/src/message.rs
index 73fa3e2..42746e4 100644
--- a/sylvia-derive/src/message.rs
+++ b/sylvia-derive/src/message.rs
@@ -54,9 +54,7 @@ impl<'a> StructMessage<'a> {
         let contract_type = &source.self_ty;
 
         let parsed = Self::parse_struct_message(source, ty);
-        let Some((method, msg_attr)) = parsed else {
-            return None;
-        };
+        let (method, msg_attr) = parsed?;
 
         let function_name = &method.sig.ident;
         let fields = process_fields(&method.sig, &mut generics_checker);
@@ -609,130 +607,13 @@ impl<'a> MsgVariant<'a> {
         }
     }
 
-    pub fn emit_multitest_proxy_methods_declaration<Generic>(
-        &self,
-        msg_ty: &MsgType,
-        custom_msg: &Type,
-        mt_app: &Type,
-        error_type: &Type,
-        generics: &[&Generic],
-    ) -> TokenStream
-    where
-        Generic: ToTokens,
-    {
-        let sylvia = crate_module();
-        let Self {
-            name,
-            fields,
-            stripped_return_type,
-            ..
-        } = self;
-
-        let params = fields.iter().map(|field| field.emit_method_field());
-        let name = Ident::new(&name.to_string().to_case(Case::Snake), name.span());
-        let enum_name = msg_ty.emit_msg_name();
-        let enum_name: Type = if !generics.is_empty() {
-            parse_quote! { #enum_name ::< #(#generics,)* > }
-        } else {
-            parse_quote! { #enum_name }
-        };
-
-        match msg_ty {
-            MsgType::Exec => quote! {
-                #[track_caller]
-                fn #name (&self, #(#params,)* ) -> #sylvia ::multitest::ExecProxy::< #error_type, #enum_name, #mt_app, #custom_msg>;
-            },
-            MsgType::Migrate => quote! {
-                #[track_caller]
-                fn #name (&self, #(#params,)* ) -> #sylvia ::multitest::MigrateProxy::< #error_type, #enum_name, #mt_app, #custom_msg>;
-            },
-            MsgType::Query => quote! {
-                fn #name (&self, #(#params,)* ) -> Result<#stripped_return_type, #error_type>;
-            },
-            MsgType::Sudo => quote! {
-                fn #name (&self, #(#params,)* ) -> Result< #sylvia ::cw_multi_test::AppResponse, #error_type>;
-            },
-            _ => quote! {},
-        }
-    }
-
-    pub fn emit_multitest_proxy_methods<Generic>(
+    pub fn emit_mt_method_definition(
         &self,
         msg_ty: &MsgType,
         custom_msg: &Type,
         mt_app: &Type,
         error_type: &Type,
-        generics: &[&Generic],
-    ) -> TokenStream
-    where
-        Generic: ToTokens,
-    {
-        let sylvia = crate_module();
-        let Self {
-            name,
-            fields,
-            stripped_return_type,
-            ..
-        } = self;
-
-        let params = fields.iter().map(|field| field.emit_method_field());
-        let arguments = fields.iter().map(MsgField::name);
-        let name = Ident::new(&name.to_string().to_case(Case::Snake), name.span());
-        let enum_name = msg_ty.emit_msg_name();
-        let enum_name: Type = if !generics.is_empty() {
-            parse_quote! { #enum_name ::< #(#generics,)* > }
-        } else {
-            parse_quote! { #enum_name }
-        };
-
-        match msg_ty {
-            MsgType::Exec => quote! {
-                #[track_caller]
-                fn #name (&self, #(#params,)* ) -> #sylvia ::multitest::ExecProxy::< #error_type, #enum_name, #mt_app, #custom_msg> {
-                    let msg = #enum_name :: #name ( #(#arguments),* );
-
-                    #sylvia ::multitest::ExecProxy::new(&self.contract_addr, msg, &self.app)
-                }
-            },
-            MsgType::Migrate => quote! {
-                #[track_caller]
-                fn #name (&self, #(#params,)* ) -> #sylvia ::multitest::MigrateProxy::< #error_type, #enum_name, #mt_app, #custom_msg> {
-                    let msg = #enum_name ::new( #(#arguments),* );
-
-                    #sylvia ::multitest::MigrateProxy::new(&self.contract_addr, msg, &self.app)
-                }
-            },
-            MsgType::Query => quote! {
-                fn #name (&self, #(#params,)* ) -> Result<#stripped_return_type, #error_type> {
-                    let msg = #enum_name :: #name ( #(#arguments),* );
-
-                    (*self.app)
-                        .querier()
-                        .query_wasm_smart(self.contract_addr.clone(), &msg)
-                        .map_err(Into::into)
-                }
-            },
-            MsgType::Sudo => quote! {
-                fn #name (&self, #(#params,)* ) -> Result< #sylvia ::cw_multi_test::AppResponse, #error_type> {
-                    let msg = #enum_name :: #name ( #(#arguments),* );
-
-                    (*self.app)
-                        .app_mut()
-                        .wasm_sudo(self.contract_addr.clone(), &msg)
-                        .map_err(|err| err.downcast().unwrap())
-                }
-            },
-            _ => quote! {},
-        }
-    }
-
-    pub fn emit_interface_multitest_proxy_methods(
-        &self,
-        msg_ty: &MsgType,
-        custom_msg: &Type,
-        mt_app: &Type,
-        error_type: &Type,
-        interface_api: &TokenStream,
+        api: &TokenStream,
     ) -> TokenStream {
         let sylvia = crate_module();
         let Self {
@@ -753,16 +634,16 @@ impl<'a> MsgVariant<'a> {
         match msg_ty {
             MsgType::Exec => quote! {
                 #[track_caller]
-                fn #name (&self, #(#params,)* ) -> #sylvia ::multitest::ExecProxy::<Self:: #error_type, #interface_api :: #type_name, #mt_app, #custom_msg> {
-                    let msg = #interface_api :: #type_name :: #name ( #(#arguments),* );
+                fn #name (&self, #(#params,)* ) -> #sylvia ::multitest::ExecProxy::< #error_type, #api :: #type_name, #mt_app, #custom_msg> {
+                    let msg = #api :: #type_name :: #name ( #(#arguments),* );
 
                     #sylvia ::multitest::ExecProxy::new(&self.contract_addr, msg, &self.app)
                 }
             },
             MsgType::Query => {
                 quote! {
-                    fn #name (&self, #(#params,)* ) -> Result<#return_type, Self:: #error_type> {
-                        let msg = #interface_api :: #type_name :: #name ( #(#arguments),* );
+                    fn #name (&self, #(#params,)* ) -> Result<#return_type, #error_type> {
+                        let msg = #api :: #type_name :: #name ( #(#arguments),* );
 
                         (*self.app)
                             .querier()
@@ -772,8 +653,8 @@ impl<'a> MsgVariant<'a> {
                 }
             }
             MsgType::Sudo => quote! {
-                fn #name (&self, #(#params,)* ) -> Result< #sylvia ::cw_multi_test::AppResponse, Self:: #error_type> {
-                    let msg = #interface_api :: #type_name :: #name ( #(#arguments),* );
+                fn #name (&self, #(#params,)* ) -> Result< #sylvia ::cw_multi_test::AppResponse, #error_type> {
+                    let msg = #api :: #type_name :: #name ( #(#arguments),* );
 
                     (*self.app)
                         .app_mut()
@@ -781,16 +662,24 @@ impl<'a> MsgVariant<'a> {
                         .map_err(|err| err.downcast().unwrap())
                 }
             },
+            MsgType::Migrate => quote! {
+                #[track_caller]
+                fn #name (&self, #(#params,)* ) -> #sylvia ::multitest::MigrateProxy::< #error_type, #api :: #type_name , #mt_app, #custom_msg> {
+                    let msg = #api :: #type_name ::new( #(#arguments),* );
+
+                    #sylvia ::multitest::MigrateProxy::new(&self.contract_addr, msg, &self.app)
+                }
+            },
             _ => quote! {},
         }
     }
 
-    pub fn emit_proxy_methods_declarations(
+    pub fn emit_mt_method_declaration(
         &self,
         msg_ty: &MsgType,
         custom_msg: &Type,
         error_type: &Type,
-        interface_enum: &TokenStream,
+        api: &TokenStream,
     ) -> TokenStream {
         let sylvia = crate_module();
         let Self {
@@ -809,15 +698,19 @@ impl<'a> MsgVariant<'a> {
 
         match msg_ty {
             MsgType::Exec => quote! {
-                fn #name (&self, #(#params,)* ) -> #sylvia ::multitest::ExecProxy::< Self:: #error_type, #interface_enum :: #type_name, MtApp, #custom_msg>;
+                fn #name (&self, #(#params,)* ) -> #sylvia ::multitest::ExecProxy::< #error_type, #api:: #type_name, MtApp, #custom_msg>;
             },
             MsgType::Query => {
                 quote! {
-                    fn #name (&self, #(#params,)* ) -> Result<#return_type, Self:: #error_type>;
+                    fn #name (&self, #(#params,)* ) -> Result<#return_type, #error_type>;
                 }
             }
             MsgType::Sudo => quote! {
-                fn #name (&self, #(#params,)* ) -> Result< #sylvia ::cw_multi_test::AppResponse, Self:: #error_type>;
+                fn #name (&self, #(#params,)* ) -> Result< #sylvia ::cw_multi_test::AppResponse, #error_type>;
+            },
+            MsgType::Migrate => quote! {
+                #[track_caller]
+                fn #name (&self, #(#params,)* ) -> #sylvia ::multitest::MigrateProxy::< #error_type, #api :: #type_name, MtApp, #custom_msg>;
             },
             _ => quote! {},
         }
@@ -940,82 +833,31 @@ where
         }
     }
 
-    pub fn emit_multitest_proxy_methods_declaration(
+    pub fn emit_mt_method_definitions(
         &self,
         custom_msg: &Type,
         mt_app: &Type,
         error_type: &Type,
+        api: &TokenStream,
     ) -> Vec<TokenStream> {
         self.variants
             .iter()
             .map(|variant| {
-                variant.emit_multitest_proxy_methods_declaration(
-                    &self.msg_ty,
-                    custom_msg,
-                    mt_app,
-                    error_type,
-                    &self.used_generics,
-                )
+                variant.emit_mt_method_definition(&self.msg_ty, custom_msg, mt_app, error_type, api)
             })
             .collect()
     }
 
-    pub fn emit_multitest_proxy_methods(
+    pub fn emit_mt_method_declarations(
         &self,
         custom_msg: &Type,
-        mt_app: &Type,
         error_type: &Type,
+        api: &TokenStream,
     ) -> Vec<TokenStream> {
         self.variants
             .iter()
             .map(|variant| {
-                variant.emit_multitest_proxy_methods(
-                    &self.msg_ty,
-                    custom_msg,
-                    mt_app,
-                    error_type,
-                    &self.used_generics,
-                )
-            })
-            .collect()
-    }
-
-    pub fn emit_interface_multitest_proxy_methods(
-        &self,
-        custom_msg: &Type,
-        mt_app: &Type,
-        error_type: &Type,
-        interface_api: &TokenStream,
-    ) -> Vec<TokenStream> {
-        self.variants
-            .iter()
-            .map(|variant| {
-                variant.emit_interface_multitest_proxy_methods(
-                    &self.msg_ty,
-                    custom_msg,
-                    mt_app,
-                    error_type,
-                    interface_api,
-                )
-            })
-            .collect()
-    }
-
-    pub fn emit_proxy_methods_declarations(
-        &self,
-        custom_msg: &Type,
-        error_type: &Type,
-        interface_enum: &TokenStream,
-    ) -> Vec<TokenStream> {
-        self.variants
-            .iter()
-            .map(|variant| {
-                variant.emit_proxy_methods_declarations(
-                    &self.msg_ty,
-                    custom_msg,
-                    error_type,
-                    interface_enum,
-                )
+                variant.emit_mt_method_declaration(&self.msg_ty, custom_msg, error_type, api)
             })
             .collect()
     }


Test patch:
diff --git a/sylvia-derive/src/multitest.rs b/sylvia-derive/src/multitest.rs
index b6f5714..135287b 100644
--- a/sylvia-derive/src/multitest.rs
+++ b/sylvia-derive/src/multitest.rs
@@ -138,33 +138,25 @@ impl<'a> ContractMtHelpers<'a> {
                 GovT,
             >
         };
+        let api = quote! { < #contract_name as #sylvia ::types::ContractApi> };
 
         let exec_methods =
-            exec_variants.emit_multitest_proxy_methods(&custom_msg, &mt_app, error_type);
+            exec_variants.emit_mt_method_definitions(&custom_msg, &mt_app, error_type, &api);
         let query_methods =
-            query_variants.emit_multitest_proxy_methods(&custom_msg, &mt_app, error_type);
+            query_variants.emit_mt_method_definitions(&custom_msg, &mt_app, error_type, &api);
         let sudo_methods =
-            sudo_variants.emit_multitest_proxy_methods(&custom_msg, &mt_app, error_type);
+            sudo_variants.emit_mt_method_definitions(&custom_msg, &mt_app, error_type, &api);
         let migrate_methods =
-            migrate_variants.emit_multitest_proxy_methods(&custom_msg, &mt_app, error_type);
+            migrate_variants.emit_mt_method_definitions(&custom_msg, &mt_app, error_type, &api);
 
-        let exec_methods_delcaration = exec_variants.emit_multitest_proxy_methods_declaration(
-            &custom_msg,
-            &mt_app,
-            error_type,
-        );
-        let query_methods_delcaration = query_variants.emit_multitest_proxy_methods_declaration(
-            &custom_msg,
-            &mt_app,
-            error_type,
-        );
-        let sudo_methods_delcaration = sudo_variants.emit_multitest_proxy_methods_declaration(
-            &custom_msg,
-            &mt_app,
-            error_type,
-        );
-        let migrate_methods_delcaration = migrate_variants
-            .emit_multitest_proxy_methods_declaration(&custom_msg, &mt_app, error_type);
+        let exec_methods_declarations =
+            exec_variants.emit_mt_method_declarations(&custom_msg, error_type, &api);
+        let query_methods_declarations =
+            query_variants.emit_mt_method_declarations(&custom_msg, error_type, &api);
+        let sudo_methods_declarations =
+            sudo_variants.emit_mt_method_declarations(&custom_msg, error_type, &api);
+        let migrate_methods_declarations =
+            migrate_variants.emit_mt_method_declarations(&custom_msg, error_type, &api);
 
         let where_predicates = where_clause
             .as_ref()
@@ -180,17 +172,17 @@ impl<'a> ContractMtHelpers<'a> {
                 use super::*;
                 use #sylvia ::cw_multi_test::Executor;
 
-                pub trait #trait_name <'app, BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, #(#generic_params,)* >
+                pub trait #trait_name <'app, MtApp, #(#generic_params,)* >
                     #where_clause
                 {
-                    #( #exec_methods_delcaration )*
-                    #( #migrate_methods_delcaration )*
-                    #( #query_methods_delcaration )*
-                    #( #sudo_methods_delcaration )*
+                    #( #exec_methods_declarations )*
+                    #( #migrate_methods_declarations )*
+                    #( #query_methods_declarations )*
+                    #( #sudo_methods_declarations )*
                 }
 
                 impl<'app, BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, #(#generic_params,)* >
-                    #trait_name <'app, BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, #(#generic_params,)* >
+                    #trait_name <'app, #mt_app, #(#generic_params,)* >
                         for #sylvia ::multitest::Proxy <'app, #mt_app, #contract_name >
                     where
                         CustomT: #sylvia ::cw_multi_test::Module,
@@ -623,7 +615,8 @@ impl<'a> TraitMtHelpers<'a> {
         let interface_name = &source.ident;
         let trait_name = Ident::new(&format!("{}Proxy", interface_name), interface_name.span());
 
-        let custom_msg: Type = parse_quote! { MultitestExecCustomType };
+        let custom_msg: Type = parse_quote! { CustomMsgT };
+        let prefixed_error_type: Type = parse_quote! { Self:: #error_type };
 
         let mt_app = parse_quote! {
             #sylvia ::cw_multi_test::App<
@@ -653,35 +646,35 @@ impl<'a> TraitMtHelpers<'a> {
             .collect();
 
         let bracketed_generics = emit_bracketed_generics(&associated_args_for_api);
-        let interface_api = quote! { < Api #bracketed_generics as #sylvia ::types::InterfaceApi> };
+        let api = quote! { < Api #bracketed_generics as #sylvia ::types::InterfaceApi> };
 
-        let associated_types_delcaration = associated_types.without_error();
+        let associated_types_declaration = associated_types.without_error();
 
-        let exec_methods = exec_variants.emit_interface_multitest_proxy_methods(
+        let exec_methods = exec_variants.emit_mt_method_definitions(
             &custom_msg,
             &mt_app,
-            error_type,
-            &interface_api,
+            &prefixed_error_type,
+            &api,
         );
-        let query_methods = query_variants.emit_interface_multitest_proxy_methods(
+        let query_methods = query_variants.emit_mt_method_definitions(
             &custom_msg,
             &mt_app,
-            error_type,
-            &interface_api,
+            &prefixed_error_type,
+            &api,
         );
-        let sudo_methods = sudo_variants.emit_interface_multitest_proxy_methods(
+        let sudo_methods = sudo_variants.emit_mt_method_definitions(
             &custom_msg,
             &mt_app,
-            error_type,
-            &interface_api,
+            &prefixed_error_type,
+            &api,
         );
 
         let exec_methods_declarations =
-            exec_variants.emit_proxy_methods_declarations(&custom_msg, error_type, &interface_api);
+            exec_variants.emit_mt_method_declarations(&custom_msg, &prefixed_error_type, &api);
         let query_methods_declarations =
-            query_variants.emit_proxy_methods_declarations(&custom_msg, error_type, &interface_api);
+            query_variants.emit_mt_method_declarations(&custom_msg, &prefixed_error_type, &api);
         let sudo_methods_declarations =
-            sudo_variants.emit_proxy_methods_declarations(&custom_msg, error_type, &interface_api);
+            sudo_variants.emit_mt_method_declarations(&custom_msg, &prefixed_error_type, &api);
 
         let where_predicates = where_clause
             .as_ref()
@@ -693,7 +686,7 @@ impl<'a> TraitMtHelpers<'a> {
 
                 pub trait #trait_name <MtApp, #custom_msg > #where_clause {
                     type #error_type: std::fmt::Debug + std::fmt::Display + Send + Sync + 'static;
-                    #(#associated_types_delcaration)*
+                    #(#associated_types_declaration)*
 
                     #(#query_methods_declarations)*
                     #(#exec_methods_declarations)*