diff --git a/examples/contracts/generic_contract/src/contract.rs b/examples/contracts/generic_contract/src/contract.rs index 8d15a695..6b226147 100644 --- a/examples/contracts/generic_contract/src/contract.rs +++ b/examples/contracts/generic_contract/src/contract.rs @@ -1,6 +1,6 @@ use cw_storage_plus::Item; use sylvia::contract; -use sylvia::cw_std::{Reply, Response, StdResult}; +use sylvia::cw_std::{Binary, Reply, Response, StdResult, SubMsgResult}; use sylvia::serde::Deserialize; use sylvia::types::{CustomMsg, ExecCtx, InstantiateCtx, MigrateCtx, QueryCtx, ReplyCtx, SudoCtx}; @@ -185,7 +185,8 @@ where fn reply( &self, _ctx: ReplyCtx, - _reply: Reply, + _result: SubMsgResult, + _payload: Binary, ) -> StdResult> { Ok(Response::new()) } diff --git a/examples/contracts/generics_forwarded/src/contract.rs b/examples/contracts/generics_forwarded/src/contract.rs index b21e5167..2bc7e8d1 100644 --- a/examples/contracts/generics_forwarded/src/contract.rs +++ b/examples/contracts/generics_forwarded/src/contract.rs @@ -1,7 +1,7 @@ use crate::error::ContractError; use cw_storage_plus::Item; use sylvia::contract; -use sylvia::cw_std::{Reply, Response}; +use sylvia::cw_std::{Binary, Response, SubMsgResult}; use sylvia::serde::Deserialize; use sylvia::types::{ CustomMsg, CustomQuery, ExecCtx, InstantiateCtx, MigrateCtx, QueryCtx, ReplyCtx, SudoCtx, @@ -195,7 +195,8 @@ where fn reply( &self, _ctx: ReplyCtx, - _reply: Reply, + _result: SubMsgResult, + _payload: Binary, ) -> Result, ContractError> { Ok(Response::new()) } diff --git a/sylvia-derive/src/contract/communication/reply.rs b/sylvia-derive/src/contract/communication/reply.rs index 1613b477..dc1c4a21 100644 --- a/sylvia-derive/src/contract/communication/reply.rs +++ b/sylvia-derive/src/contract/communication/reply.rs @@ -6,9 +6,11 @@ use itertools::Itertools; use proc_macro2::TokenStream; use proc_macro_error::emit_error; use quote::quote; +use syn::fold::Fold; use syn::{parse_quote, GenericParam, Ident, ItemImpl, Type}; use crate::crate_module; +use crate::fold::StripGenerics; use crate::parser::attributes::msg::ReplyOn; use crate::parser::MsgType; use crate::types::msg_variant::{MsgVariant, MsgVariants}; @@ -99,8 +101,7 @@ impl<'a> Reply<'a> { let match_arms = reply_id_to_data.iter().map(|(reply_id, values)| { let result_match_arms = values.iter().map(|(function_name, reply_on)| { let result_match_arm = reply_on.emit_match_arm(); - let result_match_arm_body = - reply_on.emit_match_arm_body(function_name, &self.source.self_ty); + let result_match_arm_body = self.emit_match_arm_body(reply_on, function_name); quote! { #result_match_arm => { #result_match_arm_body @@ -131,7 +132,7 @@ impl<'a> Reply<'a> { }); quote! { - pub fn dispatch_reply < #(#generics),* >( #ctx_params , msg: #sylvia ::cw_std::Reply) -> #ret_type #where_clause { + pub fn dispatch_reply < #(#generics),* >( #ctx_params , msg: #sylvia ::cw_std::Reply, contract: #contract ) -> #ret_type #where_clause { let #sylvia ::cw_std::Reply { id, payload, @@ -163,6 +164,34 @@ impl<'a> Reply<'a> { } }) } + + fn emit_match_arm_body(&self, reply_on: &ReplyOn, function_name: &Ident) -> TokenStream { + let Self { + source, generics, .. + } = self; + + let sylvia = crate_module(); + let contract = &source.self_ty; + let contract_turbo: Type = if !generics.is_empty() { + let contract_name = StripGenerics.fold_type((*contract.clone()).clone()); + parse_quote! { #contract_name :: < #(#generics),* > } + } else { + parse_quote! { #contract } + }; + + match reply_on { + ReplyOn::Success => quote! { + let #sylvia ::cw_std::SubMsgResponse { events, data, msg_responses} = response; + #contract_turbo ::new(). #function_name ((deps, env, gas_used, events, msg_responses).into(), data, payload) + }, + ReplyOn::Failure => quote! { + #contract_turbo ::new(). #function_name ((deps, env, gas_used, vec![], vec![]).into(), error, payload) + }, + ReplyOn::Always => quote! { + #contract_turbo ::new(). #function_name ((deps, env, gas_used, vec![], vec![]).into(), result, payload) + }, + } + } } trait ReplyVariants<'a> { @@ -236,7 +265,6 @@ impl AsReplyId for Ident { trait ReplyOnMethods { fn emit_match_arm(&self) -> TokenStream; - fn emit_match_arm_body(&self, function_name: &Ident, contract: &Type) -> TokenStream; } impl ReplyOnMethods for ReplyOn { @@ -249,21 +277,4 @@ impl ReplyOnMethods for ReplyOn { ReplyOn::Always => quote! { _ }, } } - - fn emit_match_arm_body(&self, function_name: &Ident, contract: &Type) -> TokenStream { - let sylvia = crate_module(); - - match self { - ReplyOn::Success => quote! { - let #sylvia ::cw_std::SubMsgResponse { events, data, msg_responses} = response; - #contract ::new(). #function_name ((deps, env, gas_used, events, msg_responses).into(), data, payload) - }, - ReplyOn::Failure => quote! { - #contract ::new(). #function_name ((deps, env, gas_used, vec![], vec![]).into(), error, payload) - }, - ReplyOn::Always => quote! { - #contract ::new(). #function_name ((deps, env, gas_used, vec![], vec![]).into(), result, payload) - }, - } - } } diff --git a/sylvia-derive/src/contract/mt.rs b/sylvia-derive/src/contract/mt.rs index 59d1af7f..57df18d2 100644 --- a/sylvia-derive/src/contract/mt.rs +++ b/sylvia-derive/src/contract/mt.rs @@ -532,8 +532,16 @@ impl<'a> MtHelpers<'a> { .get_only_variant() .as_ref() .map(|_| { + let contract_ident = get_ident_from_type(contract_name); + let contract_turbo = if !generic_params.is_empty() { + quote! { #contract_ident ::< #(#generic_params,)* > } + } else { + quote! { #contract_ident } + }; + quote! { - dispatch_reply(deps, env, msg).map_err(Into::into) + let contract = #contract_turbo ::new(); + dispatch_reply(deps, env, msg, contract).map_err(Into::into) } }) .unwrap_or_else(|| { diff --git a/sylvia-derive/src/entry_points.rs b/sylvia-derive/src/entry_points.rs index 79af7ebc..fc7ddd53 100644 --- a/sylvia-derive/src/entry_points.rs +++ b/sylvia-derive/src/entry_points.rs @@ -168,11 +168,7 @@ impl<'a> EntryPoints<'a> { fn emit_default_entry_point(&self, msg_ty: MsgType) -> TokenStream { let Self { - name, - error, - attrs, - reply, - .. + name, error, attrs, .. } = self; let sylvia = crate_module(); @@ -202,7 +198,8 @@ impl<'a> EntryPoints<'a> { }; let dispatch = match msg_ty { MsgType::Reply => quote! { - sv::dispatch_reply(deps, env, msg).map_err(Into::into) + let contract = #contract_turbo ::new(); + sv::dispatch_reply(deps, env, msg, contract).map_err(Into::into) }, _ => quote! { msg.dispatch(& #contract_turbo ::new() , ( #values )).map_err(Into::into)