Skip to content

Commit

Permalink
feat: Forward generics to custom_generic interface
Browse files Browse the repository at this point in the history
  • Loading branch information
jawoznia committed Nov 30, 2023
1 parent 7ac645e commit 66287d2
Show file tree
Hide file tree
Showing 14 changed files with 140 additions and 47 deletions.
1 change: 1 addition & 0 deletions examples/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/contracts/generic_contract/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub struct GenericContract<InstantiateT, ExecT, QueryT, MigrateT, FieldT> {
#[contract]
#[messages(cw1 as Cw1: custom(msg, query))]
#[messages(generic<SvCustomMsg, SvCustomMsg, SvCustomMsg> as Generic: custom(msg, query))]
#[messages(custom_and_generic<SvCustomMsg, SvCustomMsg, SvCustomQuery, sylvia::types::SvCustomMsg> as CustomAndGeneric)]
#[messages(custom_and_generic<SvCustomMsg, SvCustomMsg,SvCustomMsg, SvCustomQuery, sylvia::types::SvCustomMsg> as CustomAndGeneric)]
#[sv::custom(msg=SvCustomMsg, query=SvCustomQuery)]
impl<InstantiateT, ExecT, QueryT, MigrateT, FieldT>
GenericContract<InstantiateT, ExecT, QueryT, MigrateT, FieldT>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ impl<InstantiateT, ExecT, QueryT, MigrateT, FieldT>
CustomAndGeneric<
SvCustomMsg,
SvCustomMsg,
sylvia::types::SvCustomQuery,
SvCustomMsg,
sylvia::types::SvCustomMsg,
sylvia::types::SvCustomQuery,
> for crate::contract::GenericContract<InstantiateT, ExecT, QueryT, MigrateT, FieldT>
{
type Error = StdError;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub struct NonGenericContract;
#[cfg_attr(not(feature = "library"), entry_points)]
#[contract]
#[messages(generic<SvCustomMsg, sylvia::types::SvCustomMsg, SvCustomMsg> as Generic: custom(msg, query))]
#[messages(custom_and_generic<SvCustomMsg, SvCustomMsg, SvCustomQuery, sylvia::types::SvCustomMsg> as CustomAndGeneric)]
#[messages(custom_and_generic<SvCustomMsg, SvCustomMsg,SvCustomMsg, SvCustomQuery, sylvia::types::SvCustomMsg> as CustomAndGeneric)]
#[messages(cw1 as Cw1: custom(msg, query))]
/// Required if interface returns generic `Response`
#[sv::custom(msg=SvCustomMsg, query=SvCustomQuery)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ use sylvia::types::{ExecCtx, QueryCtx, SvCustomMsg, SvCustomQuery};
#[contract(module = crate::contract)]
#[messages(custom_and_generic as CustomAndGeneric)]
#[sv::custom(msg=sylvia::types::SvCustomMsg, query=SvCustomQuery)]
impl CustomAndGeneric<SvCustomMsg, SvCustomMsg, SvCustomQuery, sylvia::types::SvCustomMsg>
for crate::contract::NonGenericContract
impl
CustomAndGeneric<
SvCustomMsg,
SvCustomMsg,
SvCustomMsg,
sylvia::types::SvCustomMsg,
SvCustomQuery,
> for crate::contract::NonGenericContract
{
type Error = StdError;

Expand Down
1 change: 1 addition & 0 deletions examples/contracts/generics_forwarded/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ cw-utils = { workspace = true }
serde = { workspace = true }
sylvia = { path = "../../../sylvia" }
generic = { path = "../../interfaces/generic" }
custom-and-generic = { path = "../../interfaces/custom-and-generic/" }

[dev-dependencies]
anyhow = { workspace = true }
Expand Down
6 changes: 3 additions & 3 deletions examples/contracts/generics_forwarded/src/bin/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ use cosmwasm_schema::write_api;
#[cfg(not(tarpaulin_include))]
fn main() {
use generics_forwarded::contract::sv::{ContractExecMsg, ContractQueryMsg, InstantiateMsg};
use sylvia::types::SvCustomMsg;
use sylvia::types::{SvCustomMsg, SvCustomQuery};

write_api! {
instantiate: InstantiateMsg<SvCustomMsg>,
execute: ContractExecMsg<SvCustomMsg, SvCustomMsg>,
query: ContractQueryMsg<SvCustomMsg, SvCustomMsg>,
execute: ContractExecMsg<SvCustomMsg, SvCustomMsg, SvCustomMsg,SvCustomQuery>,
query: ContractQueryMsg<SvCustomMsg, SvCustomMsg, SvCustomMsg,SvCustomQuery>,
}
}
12 changes: 6 additions & 6 deletions examples/contracts/generics_forwarded/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use cosmwasm_std::{Reply, Response, StdResult};
use cw_storage_plus::Item;
use serde::de::DeserializeOwned;
use serde::Deserialize;
use sylvia::types::{
CustomMsg, CustomQuery, ExecCtx, InstantiateCtx, MigrateCtx, QueryCtx, ReplyCtx, SvCustomMsg,
Expand Down Expand Up @@ -29,6 +28,7 @@ pub struct GenericsForwardedContract<

#[contract]
#[messages(generic<ExecT, QueryT, SvCustomMsg> as Generic: custom(msg, query))]
#[messages(custom_and_generic<ExecT, QueryT, SvCustomMsg,CustomMsgT, CustomQueryT> as CustomAndGeneric)]
#[sv::custom(msg=CustomMsgT, query=CustomQueryT)]
impl<InstantiateT, ExecT, QueryT, MigrateT, CustomMsgT, CustomQueryT, FieldT>
GenericsForwardedContract<
Expand All @@ -41,11 +41,11 @@ impl<InstantiateT, ExecT, QueryT, MigrateT, CustomMsgT, CustomQueryT, FieldT>
FieldT,
>
where
for<'msg_de> InstantiateT: CustomMsg + Deserialize<'msg_de> + 'msg_de,
ExecT: CustomMsg + DeserializeOwned + 'static,
QueryT: CustomMsg + DeserializeOwned + 'static,
MigrateT: CustomMsg + DeserializeOwned + 'static,
CustomMsgT: CustomMsg + DeserializeOwned + 'static,
for<'msg_de> InstantiateT: cosmwasm_std::CustomMsg + Deserialize<'msg_de> + 'msg_de,
ExecT: CustomMsg + 'static,
QueryT: CustomMsg + 'static,
MigrateT: CustomMsg + 'static,
CustomMsgT: CustomMsg + 'static,
CustomQueryT: CustomQuery + 'static,
FieldT: 'static,
{
Expand Down
84 changes: 84 additions & 0 deletions examples/contracts/generics_forwarded/src/custom_and_generic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use cosmwasm_std::{CosmosMsg, Response, StdError, StdResult};
use custom_and_generic::CustomAndGeneric;
use serde::Deserialize;
use sylvia::contract;
use sylvia::types::{CustomMsg, CustomQuery, ExecCtx, QueryCtx, SvCustomMsg};

#[contract(module = crate::contract)]
#[messages(custom_and_generic as CustomAndGeneric)]
#[sv::custom(msg=CustomMsgT, query=CustomQueryT)]
impl<InstantiateT, ExecT, QueryT, MigrateT, CustomMsgT, CustomQueryT, FieldT>
CustomAndGeneric<ExecT, QueryT, SvCustomMsg, CustomMsgT, CustomQueryT>
for crate::contract::GenericsForwardedContract<
InstantiateT,
ExecT,
QueryT,
MigrateT,
CustomMsgT,
CustomQueryT,
FieldT,
>
where
for<'msg_de> InstantiateT: cosmwasm_std::CustomMsg + Deserialize<'msg_de> + 'msg_de,
ExecT: CustomMsg + 'static,
QueryT: CustomMsg + 'static,
MigrateT: CustomMsg + 'static,
CustomMsgT: CustomMsg + 'static,
CustomQueryT: CustomQuery + 'static,
FieldT: 'static,
{
type Error = StdError;

#[msg(exec)]
fn custom_generic_execute(
&self,
_ctx: ExecCtx<CustomQueryT>,
_msgs: Vec<CosmosMsg<ExecT>>,
) -> StdResult<Response<CustomMsgT>> {
Ok(Response::new())
}

#[msg(query)]
fn custom_generic_query(
&self,
_ctx: QueryCtx<CustomQueryT>,
_msg: QueryT,
) -> StdResult<SvCustomMsg> {
Ok(SvCustomMsg {})
}
}

#[cfg(test)]
mod tests {
use super::sv::test_utils::CustomAndGeneric;
use crate::contract::sv::multitest_utils::CodeId;
use sylvia::multitest::App;
use sylvia::types::{SvCustomMsg, SvCustomQuery};

#[test]
fn proxy_methods() {
let app = App::<cw_multi_test::BasicApp<SvCustomMsg, SvCustomQuery>>::custom(|_, _, _| {});
let code_id = CodeId::<
SvCustomMsg,
sylvia::types::SvCustomMsg,
SvCustomMsg,
SvCustomMsg,
SvCustomMsg,
SvCustomQuery,
String,
_,
>::store_code(&app);

let owner = "owner";

let contract = code_id
.instantiate(SvCustomMsg {})
.with_label("GenericContract")
.with_admin(owner)
.call(owner)
.unwrap();

contract.custom_generic_execute(vec![]).call(owner).unwrap();
contract.custom_generic_query(SvCustomMsg {}).unwrap();
}
}
15 changes: 7 additions & 8 deletions examples/contracts/generics_forwarded/src/generic.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use cosmwasm_std::{CosmosMsg, CustomMsg, Response, StdError, StdResult};
use cosmwasm_std::{CosmosMsg, Response, StdError, StdResult};
use generic::Generic;
use serde::de::DeserializeOwned;
use serde::Deserialize;
use sylvia::contract;
use sylvia::types::{CustomQuery, ExecCtx, QueryCtx, SvCustomMsg};
use sylvia::types::{CustomMsg, CustomQuery, ExecCtx, QueryCtx, SvCustomMsg};

#[contract(module = crate::contract)]
#[messages(generic as Generic)]
Expand All @@ -20,11 +19,11 @@ impl<InstantiateT, ExecT, QueryT, MigrateT, CustomMsgT, CustomQueryT, FieldT>
FieldT,
>
where
for<'msg_de> InstantiateT: CustomMsg + Deserialize<'msg_de> + 'msg_de,
ExecT: CustomMsg + DeserializeOwned + 'static,
QueryT: CustomMsg + DeserializeOwned + 'static,
MigrateT: CustomMsg + DeserializeOwned + 'static,
CustomMsgT: CustomMsg + DeserializeOwned + 'static,
for<'msg_de> InstantiateT: cosmwasm_std::CustomMsg + Deserialize<'msg_de> + 'msg_de,
ExecT: CustomMsg + 'static,
QueryT: CustomMsg + 'static,
MigrateT: CustomMsg + 'static,
CustomMsgT: CustomMsg + 'static,
CustomQueryT: CustomQuery + 'static,
FieldT: 'static,
{
Expand Down
1 change: 1 addition & 0 deletions examples/contracts/generics_forwarded/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod contract;
pub mod custom_and_generic;
pub mod generic;
29 changes: 15 additions & 14 deletions examples/interfaces/custom-and-generic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,30 @@ use sylvia::types::{ExecCtx, QueryCtx};
use sylvia::{interface, schemars};

#[interface]
#[sv::custom(msg=RetType, query=CtxQuery)]
pub trait CustomAndGeneric<ExecParam, QueryParam, CtxQuery, RetType>
#[sv::custom(msg=CustomMsgT, query=CustomQueryT)]
pub trait CustomAndGeneric<ExecT, QueryT, RetT, CustomMsgT, CustomQueryT>
where
for<'msg_de> ExecParam: CustomMsg + Deserialize<'msg_de>,
QueryParam: sylvia::types::CustomMsg,
CtxQuery: sylvia::types::CustomQuery,
RetType: CustomMsg + DeserializeOwned,
for<'msg_de> ExecT: CustomMsg + Deserialize<'msg_de>,
QueryT: sylvia::types::CustomMsg,
RetT: CustomMsg + DeserializeOwned,
CustomMsgT: CustomMsg + DeserializeOwned,
CustomQueryT: sylvia::types::CustomQuery,
{
type Error: From<StdError>;

#[msg(exec)]
fn custom_generic_execute(
&self,
ctx: ExecCtx<CtxQuery>,
msgs: Vec<CosmosMsg<ExecParam>>,
) -> Result<Response<RetType>, Self::Error>;
ctx: ExecCtx<CustomQueryT>,
msgs: Vec<CosmosMsg<ExecT>>,
) -> Result<Response<CustomMsgT>, Self::Error>;

#[msg(query)]
fn custom_generic_query(
&self,
ctx: QueryCtx<CtxQuery>,
param: QueryParam,
) -> Result<RetType, Self::Error>;
ctx: QueryCtx<CustomQueryT>,
param: QueryT,
) -> Result<RetT, Self::Error>;
}

#[cfg(test)]
Expand Down Expand Up @@ -59,11 +60,11 @@ mod tests {

// Construct messages with Interface extension
let _ =
<super::sv::Api<SvCustomMsg, _, SvCustomQuery, SvCustomMsg> as InterfaceApi>::Query::custom_generic_query(
<super::sv::Api<SvCustomMsg, _, SvCustomMsg, SvCustomQuery, SvCustomMsg> as InterfaceApi>::Query::custom_generic_query(
SvCustomMsg {},
);
let _=
<super::sv::Api<_, SvCustomMsg, SvCustomQuery,cosmwasm_std::Empty> as InterfaceApi>::Exec::custom_generic_execute(
<super::sv::Api<_, SvCustomMsg,SvCustomMsg, SvCustomQuery,cosmwasm_std::Empty> as InterfaceApi>::Exec::custom_generic_execute(
vec![ CosmosMsg::Custom(SvCustomMsg{}),
]);
}
Expand Down
16 changes: 7 additions & 9 deletions sylvia-derive/src/multitest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ impl<'a> MultitestHelpers<'a> {
.unwrap_or(quote! {});

let custom_msg = custom.msg_or_default();
let custom_query = custom.query_or_default();

#[cfg(not(tarpaulin_include))]
let mt_app = parse_quote! {
Expand Down Expand Up @@ -358,12 +359,9 @@ impl<'a> MultitestHelpers<'a> {

let mut generics_checker = CheckGenerics::new(generic_params);
generics_checker.visit_type(&custom_msg);
let (custom_generic, _) = generics_checker.used_unused();
let custom_generic = custom_generic.first();
let custom_where_predicate = match custom_generic {
Some(generic) => filter_wheres(where_clause, generic_params, &[generic]),
None => vec![],
};
generics_checker.visit_type(&custom_query);
let (custom_generics, _) = generics_checker.used_unused();
let custom_where_predicate = filter_wheres(where_clause, generic_params, &custom_generics);
let exec_where_predicates = filter_wheres(where_clause, generic_params, exec_generics);
let query_where_predicates = filter_wheres(where_clause, generic_params, query_generics);
let trait_where_clause = if !exec_where_predicates.is_empty() {
Expand All @@ -389,12 +387,12 @@ impl<'a> MultitestHelpers<'a> {
pub mod test_utils {
use super::*;

pub trait #trait_name<MtApp, #(#exec_generics,)* #(#query_generics,)* #custom_generic > #trait_where_clause {
pub trait #trait_name<MtApp, #(#exec_generics,)* #(#query_generics,)* #(#custom_generics,)* > #trait_where_clause {
#(#query_methods_declarations)*
#(#exec_methods_declarations)*
}

impl<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, #(#exec_generics,)* #(#query_generics,)* #custom_generic> #trait_name< #mt_app , #(#exec_generics,)* #(#query_generics,)* #custom_generic > for #module sv::trait_utils:: #proxy_name<'_, #mt_app >
impl<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, #(#exec_generics,)* #(#query_generics,)* #(#custom_generics,)*> #trait_name< #mt_app , #(#exec_generics,)* #(#query_generics,)* #(#custom_generics,)* > for #module sv::trait_utils:: #proxy_name<'_, #mt_app >
where
CustomT: #sylvia ::cw_multi_test::Module,
WasmT: #sylvia ::cw_multi_test::Wasm<CustomT::ExecT, CustomT::QueryT>,
Expand Down Expand Up @@ -422,7 +420,7 @@ impl<'a> MultitestHelpers<'a> {
#(#exec_methods)*
}

impl<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, #(#contract_generics,)* > #trait_name< #mt_app , #(#exec_generics,)* #(#query_generics,)* #custom_generic > for #contract_module sv::multitest_utils:: #contract_proxy <'_, #mt_app, #(#contract_generics,)* >
impl<BankT, ApiT, StorageT, CustomT, WasmT, StakingT, DistrT, IbcT, GovT, #(#contract_generics,)* > #trait_name< #mt_app , #(#exec_generics,)* #(#query_generics,)* #(#custom_generics,)* > for #contract_module sv::multitest_utils:: #contract_proxy <'_, #mt_app, #(#contract_generics,)* >
where
CustomT: #sylvia ::cw_multi_test::Module,
WasmT: #sylvia ::cw_multi_test::Wasm<CustomT::ExecT, CustomT::QueryT>,
Expand Down
5 changes: 3 additions & 2 deletions sylvia/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Deps, DepsMut, Empty, Env, MessageInfo};
use schemars::JsonSchema;
use serde::de::DeserializeOwned;

pub struct ReplyCtx<'a, C: cosmwasm_std::CustomQuery = Empty> {
Expand Down Expand Up @@ -102,9 +103,9 @@ pub trait CustomMsg: cosmwasm_std::CustomMsg + DeserializeOwned {}

impl<T> CustomMsg for T where T: cosmwasm_std::CustomMsg + DeserializeOwned {}

pub trait CustomQuery: cosmwasm_std::CustomQuery + DeserializeOwned {}
pub trait CustomQuery: cosmwasm_std::CustomQuery + DeserializeOwned + JsonSchema {}

impl<T> CustomQuery for T where T: cosmwasm_std::CustomQuery + DeserializeOwned {}
impl<T> CustomQuery for T where T: cosmwasm_std::CustomQuery + DeserializeOwned + JsonSchema {}

#[cw_serde]
pub struct SvCustomMsg;
Expand Down

0 comments on commit 66287d2

Please sign in to comment.