Skip to content

Commit

Permalink
feat: Impl ContractApi extension trait
Browse files Browse the repository at this point in the history
  • Loading branch information
jawoznia committed Oct 30, 2023
1 parent 9d44792 commit 2e4a7ac
Show file tree
Hide file tree
Showing 8 changed files with 277 additions and 21 deletions.
6 changes: 3 additions & 3 deletions examples/interfaces/custom-and-generic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ where
mod tests {
use cosmwasm_std::testing::mock_dependencies;
use cosmwasm_std::{Addr, CosmosMsg, Empty, QuerierWrapper};
use sylvia::types::{InterfaceMessages, SvCustomMsg};
use sylvia::types::{InterfaceApi, SvCustomMsg};

use crate::sv::Querier;

Expand All @@ -58,11 +58,11 @@ mod tests {

// Construct messages with Interface extension
let _ =
<super::sv::InterfaceTypes<SvCustomMsg, _, SvCustomMsg> as InterfaceMessages>::Query::custom_generic_query(
<super::sv::Api<SvCustomMsg, _, SvCustomMsg> as InterfaceApi>::Query::custom_generic_query(
SvCustomMsg {},
);
let _=
<super::sv::InterfaceTypes<_, SvCustomMsg, cosmwasm_std::Empty> as InterfaceMessages>::Exec::custom_generic_execute(
<super::sv::Api<_, SvCustomMsg, cosmwasm_std::Empty> as InterfaceApi>::Exec::custom_generic_execute(
vec![ CosmosMsg::Custom(SvCustomMsg{}),
]);
}
Expand Down
11 changes: 5 additions & 6 deletions examples/interfaces/generic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ where
#[cfg(test)]
mod tests {
use cosmwasm_std::{testing::mock_dependencies, Addr, CosmosMsg, Empty, QuerierWrapper};
use sylvia::types::{InterfaceMessages, SvCustomMsg};
use sylvia::types::{InterfaceApi, SvCustomMsg};

use crate::sv::Querier;

Expand All @@ -49,12 +49,11 @@ mod tests {
let _: Result<SvCustomMsg, _> = querier.generic_query(SvCustomMsg {});

// Construct messages with Interface extension
let _ =
<super::sv::InterfaceTypes<SvCustomMsg, _, SvCustomMsg> as InterfaceMessages>::Query::generic_query(
SvCustomMsg {},
);
let _ = <super::sv::Api<SvCustomMsg, _, SvCustomMsg> as InterfaceApi>::Query::generic_query(
SvCustomMsg {},
);
let _=
<super::sv::InterfaceTypes<_, SvCustomMsg, cosmwasm_std::Empty> as InterfaceMessages>::Exec::generic_exec(vec![
<super::sv::Api<_, SvCustomMsg, cosmwasm_std::Empty> as InterfaceApi>::Exec::generic_exec(vec![
CosmosMsg::Custom(SvCustomMsg{}),
]);
}
Expand Down
15 changes: 12 additions & 3 deletions sylvia-derive/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ use crate::check_generics::GetPath;
use crate::crate_module;
use crate::interfaces::Interfaces;
use crate::message::{
ContractEnumMessage, EnumMessage, GlueMessage, InterfaceMessages, MsgVariants, StructMessage,
ContractApi, ContractEnumMessage, EnumMessage, GlueMessage, InterfaceApi, MsgVariants,
StructMessage,
};
use crate::multitest::{MultitestHelpers, TraitMultitestHelpers};
use crate::parser::{ContractArgs, ContractErrorAttr, Custom, MsgType, OverrideEntryPoints};
Expand Down Expand Up @@ -77,7 +78,7 @@ impl<'a> TraitInput<'a> {
)
.emit_querier();

let interface_messages = InterfaceMessages::new(self.item, &self.generics).emit();
let interface_messages = InterfaceApi::new(self.item, &self.generics).emit();

#[cfg(not(tarpaulin_include))]
{
Expand Down Expand Up @@ -189,7 +190,12 @@ impl<'a> ImplInput<'a> {
}

fn process_contract(&self) -> TokenStream {
let Self { item, generics, .. } = self;
let Self {
item,
generics,
custom,
..
} = self;
let multitest_helpers = self.emit_multitest_helpers(generics);
let where_clause = &item.generics.where_clause;

Expand All @@ -203,6 +209,7 @@ impl<'a> ImplInput<'a> {
let messages = self.emit_messages();
let remote = Remote::new(&self.interfaces).emit();
let querier_from_impl = self.interfaces.emit_querier_from_impl();
let contract_api = ContractApi::new(item, generics, custom).emit();

#[cfg(not(tarpaulin_include))]
{
Expand All @@ -219,6 +226,8 @@ impl<'a> ImplInput<'a> {
#querier

#(#querier_from_impl)*

#contract_api
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions sylvia-derive/src/interfaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl Interfaces {
};

let interface_enum =
quote! { <#module ::sv::InterfaceTypes #generics as #sylvia ::types::InterfaceMessages> };
quote! { <#module ::sv::Api #generics as #sylvia ::types::InterfaceApi> };
if msg_ty == &MsgType::Query {
quote! { #variant ( #interface_enum :: Query) }
} else {
Expand Down Expand Up @@ -161,7 +161,7 @@ impl Interfaces {

let type_name = msg_ty.as_accessor_name();
quote! {
<#module ::sv::InterfaceTypes #generics as #sylvia ::types::InterfaceMessages> :: #type_name :: response_schemas_impl()
<#module ::sv::Api #generics as #sylvia ::types::InterfaceApi> :: #type_name :: response_schemas_impl()
}
})
.collect()
Expand Down
111 changes: 106 additions & 5 deletions sylvia-derive/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,8 @@ impl<'a> MsgVariant<'a> {
let params = fields.iter().map(|field| field.emit_method_field());
let arguments = fields.iter().map(MsgField::name);
let bracketed_generics = emit_bracketed_generics(generics);
let interface_enum = quote! { < #module sv::InterfaceTypes #bracketed_generics as #sylvia ::types::InterfaceMessages> };
let interface_enum =
quote! { < #module sv::Api #bracketed_generics as #sylvia ::types::InterfaceApi> };
let type_name = msg_ty.as_accessor_name();
let name = Ident::new(&name.to_string().to_case(Case::Snake), name.span());

Expand Down Expand Up @@ -1434,13 +1435,113 @@ impl<'a> GlueMessage<'a> {
}
}

pub struct InterfaceMessages<'a> {
pub struct ContractApi<'a> {
source: &'a ItemImpl,
exec_variants: MsgVariants<'a, GenericParam>,
query_variants: MsgVariants<'a, GenericParam>,
instantiate_variants: MsgVariants<'a, GenericParam>,
migrate_variants: MsgVariants<'a, GenericParam>,
generics: &'a [&'a GenericParam],
custom: &'a Custom<'a>,
}

impl<'a> ContractApi<'a> {
pub fn new(
source: &'a ItemImpl,
generics: &'a [&'a GenericParam],
custom: &'a Custom<'a>,
) -> Self {
let exec_variants = MsgVariants::new(
source.as_variants(),
MsgType::Exec,
generics,
&source.generics.where_clause,
);

let query_variants = MsgVariants::new(
source.as_variants(),
MsgType::Query,
generics,
&source.generics.where_clause,
);

let instantiate_variants = MsgVariants::new(
source.as_variants(),
MsgType::Instantiate,
generics,
&source.generics.where_clause,
);

let migrate_variants = MsgVariants::new(
source.as_variants(),
MsgType::Migrate,
generics,
&source.generics.where_clause,
);

Self {
source,
exec_variants,
query_variants,
instantiate_variants,
migrate_variants,
generics,
custom,
}
}

pub fn emit(&self) -> TokenStream {
let sylvia = crate_module();
let Self {
source,
exec_variants,
query_variants,
instantiate_variants,
migrate_variants,
generics,
custom,
} = self;

let contract_name = &source.self_ty;
let exec_generics = &exec_variants.used_generics;
let query_generics = &query_variants.used_generics;
let instantiate_generics = &instantiate_variants.used_generics;
let migrate_generics = &migrate_variants.used_generics;

let bracket_generics = emit_bracketed_generics(generics);
let exec_bracketed_generics = emit_bracketed_generics(exec_generics);
let query_bracketed_generics = emit_bracketed_generics(query_generics);
let instantiate_bracketed_generics = emit_bracketed_generics(instantiate_generics);
let migrate_bracketed_generics = emit_bracketed_generics(migrate_generics);

let migrate_type = match !migrate_variants.variants().is_empty() {
true => quote! { type Migrate = MigrateMsg #migrate_bracketed_generics; },
false => quote! { type Migrate = #sylvia ::cw_std::Empty; },
};
let custom_query = custom.query_or_default();

quote! {
impl #bracket_generics #sylvia ::types::ContractApi for #contract_name {
type ContractExec = ContractExecMsg #exec_bracketed_generics;
type ContractQuery = ContractQueryMsg #query_bracketed_generics;
type Exec = ExecMsg #exec_bracketed_generics;
type Query = QueryMsg #query_bracketed_generics;
type Instantiate = InstantiateMsg #instantiate_bracketed_generics;
#migrate_type
type Remote = Remote<'static>;
type Querier = BoundQuerier<'static, #custom_query >;
}
}
}
}

pub struct InterfaceApi<'a> {
exec_variants: MsgVariants<'a, GenericParam>,
query_variants: MsgVariants<'a, GenericParam>,
generics: &'a [&'a GenericParam],
}

impl<'a> InterfaceMessages<'a> {
impl<'a> InterfaceApi<'a> {
pub fn new(source: &'a ItemTrait, generics: &'a [&'a GenericParam]) -> Self {
let exec_variants = MsgVariants::new(
source.as_variants(),
Expand Down Expand Up @@ -1487,11 +1588,11 @@ impl<'a> InterfaceMessages<'a> {
};

quote! {
pub struct InterfaceTypes #bracket_generics {
pub struct Api #bracket_generics {
#phantom
}

impl #bracket_generics #sylvia ::types::InterfaceMessages for InterfaceTypes #bracket_generics {
impl #bracket_generics #sylvia ::types::InterfaceApi for Api #bracket_generics {
type Exec = ExecMsg #exec_bracketed_generics;
type Query = QueryMsg #query_bracketed_generics;
}
Expand Down
3 changes: 2 additions & 1 deletion sylvia-derive/src/multitest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,8 @@ where
};

let bracketed_generics = emit_bracketed_generics(generics);
let interface_enum = quote! { < #module sv::InterfaceTypes #bracketed_generics as #sylvia ::types::InterfaceMessages> };
let interface_enum =
quote! { < #module sv::Api #bracketed_generics as #sylvia ::types::InterfaceApi> };

let exec_methods = exec_variants.emit_interface_multitest_proxy_methods(
&custom_msg,
Expand Down
13 changes: 12 additions & 1 deletion sylvia/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,18 @@ pub struct SvCustomMsg;

impl cosmwasm_std::CustomMsg for SvCustomMsg {}

pub trait InterfaceMessages {
pub trait InterfaceApi {
type Exec;
type Query;
}

pub trait ContractApi {
type Instantiate;
type Query;
type Exec;
type ContractQuery;
type ContractExec;
type Migrate;
type Querier;
type Remote;
}
Loading

0 comments on commit 2e4a7ac

Please sign in to comment.