Skip to content

Commit

Permalink
Merge branch 'main' into jawoznia/sylvia/update_deps
Browse files Browse the repository at this point in the history
  • Loading branch information
kulikthebird committed Jul 3, 2024
2 parents 9880f60 + 55e9667 commit 9d62c3c
Show file tree
Hide file tree
Showing 27 changed files with 1,050 additions and 190 deletions.
5 changes: 3 additions & 2 deletions 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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ sylvia-derive = { version = "1.0.2", path = "sylvia-derive" }
anyhow = "1.0.86"
cosmwasm-schema = "2.0.4"
cosmwasm-std = "2.0.4"
cw-multi-test = { git = "https://github.com/CosmWasm/cw-multi-test" }
cw-multi-test = "2.1.0-rc.1"
cw-storage-plus = "2.0.0"
schemars = "0.8.21"
cw-utils = "2.0.0"
Expand Down
5 changes: 3 additions & 2 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/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ edition = "2021"
anyhow = "1.0.86"
cosmwasm-schema = "2.0.4"
cosmwasm-std = "2.0.4"
cw-multi-test = { git = "https://github.com/CosmWasm/cw-multi-test" }
cw-multi-test = "2.1.0-rc.1"
cw-storage-plus = "2.0.0"
cw-utils = "2.0.0"
cw2 = "2.0.0"
Expand Down
195 changes: 195 additions & 0 deletions sylvia-derive/src/executor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
use convert_case::Case;
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use syn::{GenericParam, Generics, Ident, Type};

use crate::associated_types::{AssociatedTypes, EmitAssociated, ItemType};
use crate::check_generics::GetPath;
use crate::crate_module;
use crate::message::{MsgField, MsgVariant, MsgVariants};
use crate::parser::attributes::msg::MsgType;
use crate::utils::{emit_bracketed_generics, SvCasing};

pub struct InterfaceExecutor<'a, Generic> {
variants: &'a MsgVariants<'a, Generic>,
associated_types: &'a AssociatedTypes<'a>,
interface_name: &'a Ident,
}

impl<'a, Generic> InterfaceExecutor<'a, Generic>
where
Generic: GetPath + PartialEq + ToTokens,
{
pub fn new(
variants: &'a MsgVariants<'a, Generic>,
associated_types: &'a AssociatedTypes,
interface_name: &'a Ident,
) -> Self {
Self {
variants,
associated_types,
interface_name,
}
}

pub fn emit_executor_trait(&self) -> TokenStream {
let sylvia = crate_module();
let Self {
variants,
associated_types,
interface_name,
} = self;

let generics: Vec<_> = associated_types
.without_special()
.map(ItemType::as_name)
.collect();
let all_generics: Vec<_> = associated_types.all_names().collect();
let assoc_types: Vec<_> = generics
.iter()
.map(|assoc| quote! {Self:: #assoc})
.collect();
let bracketed_generics = emit_bracketed_generics(&assoc_types);

let accessor = MsgType::Exec.as_accessor_name();
let executor_api_path =
quote! { < Api #bracketed_generics as #sylvia ::types::InterfaceApi>:: #accessor };

let methods_trait_impl = variants
.variants()
.map(|variant| variant.emit_executor_impl(&executor_api_path))
.collect::<Vec<_>>();

let executor_methods_declaration = variants
.variants()
.map(|variant| variant.emit_executor_method_declaration());

let types_declaration = associated_types.filtered().collect::<Vec<_>>();
let where_clause = associated_types.as_where_clause();

quote! {
pub trait Executor {
#(#types_declaration)*
#(#executor_methods_declaration)*
}

impl <#(#all_generics,)*> Executor
for #sylvia ::types::ExecutorBuilder<(#sylvia ::types::EmptyExecutorBuilderState, dyn #interface_name <#( #all_generics = #all_generics,)* > ) > #where_clause {
#(type #generics = #generics;)*
#(#methods_trait_impl)*
}

impl <Contract: #interface_name> Executor
for #sylvia ::types::ExecutorBuilder<( #sylvia ::types::EmptyExecutorBuilderState, Contract )> {
#(type #generics = <Contract as #interface_name > :: #generics;)*
#(#methods_trait_impl)*
}
}
}
}

pub struct ContractExecutor<'a> {
generics: Generics,
self_ty: Type,
variants: MsgVariants<'a, GenericParam>,
}

impl<'a> ContractExecutor<'a> {
pub fn new(generics: Generics, self_ty: Type, variants: MsgVariants<'a, GenericParam>) -> Self {
Self {
generics,
self_ty,
variants,
}
}

pub fn emit(&self) -> TokenStream {
let sylvia = crate_module();
let Self {
generics,
self_ty,
variants,
..
} = self;

let where_clause = &generics.where_clause;
let generics: Vec<_> = generics.params.iter().collect();
let contract = &self_ty;

let accessor = MsgType::Exec.as_accessor_name();
let executor_api_path = quote! { < #contract as #sylvia ::types::ContractApi>:: #accessor };

let executor_methods_impl = variants
.variants()
.map(|variant| variant.emit_executor_impl(&executor_api_path));

let executor_methods_declaration = variants
.variants()
.map(|variant| variant.emit_executor_method_declaration());

let types_declaration = where_clause
.as_ref()
.map(EmitAssociated::emit_declaration)
.unwrap_or(vec![]);

let types_implementation = where_clause
.as_ref()
.map(EmitAssociated::emit_implementation)
.unwrap_or(vec![]);

quote! {
pub trait Executor<#(#generics,)*> #where_clause {
#(#types_declaration)*
#(#executor_methods_declaration)*
}

impl <#(#generics,)*> Executor<#(#generics,)*>
for #sylvia ::types::ExecutorBuilder<( #sylvia ::types::EmptyExecutorBuilderState, #contract )> #where_clause {
#(#types_implementation)*
#(#executor_methods_impl)*
}
}
}
}

trait EmitExecutorMethod {
fn emit_executor_impl(&self, api_path: &TokenStream) -> TokenStream;
fn emit_executor_method_declaration(&self) -> TokenStream;
}

impl EmitExecutorMethod for MsgVariant<'_> {
fn emit_executor_impl(&self, api_path: &TokenStream) -> TokenStream {
let name = self.name();
let fields = self.fields();
let sylvia = crate_module();

let parameters = fields.iter().map(MsgField::emit_method_field_folded);
let fields_names = fields.iter().map(MsgField::name);
let variant_name = name.to_case(Case::Snake);

quote! {
fn #variant_name(self, #(#parameters),*) -> Result<#sylvia ::types::ExecutorBuilder< #sylvia ::types::ReadyExecutorBuilderState >, #sylvia ::cw_std::StdError> {
Ok(#sylvia ::types::ExecutorBuilder::<#sylvia ::types::ReadyExecutorBuilderState>::new(
self.contract().to_owned(),
self.funds().to_owned(),
#sylvia ::cw_std::to_json_binary( & #api_path :: #variant_name (#(#fields_names),*) )?,
))
}
}
}

fn emit_executor_method_declaration(&self) -> TokenStream {
let name = self.name();
let sylvia = crate_module();

let parameters = self
.fields()
.iter()
.map(|field| field.emit_method_field_folded());
let variant_name = name.to_case(Case::Snake);

quote! {
fn #variant_name(self, #(#parameters),*) -> Result< #sylvia ::types::ExecutorBuilder<#sylvia ::types::ReadyExecutorBuilderState>, #sylvia ::cw_std::StdError>;
}
}
}
30 changes: 26 additions & 4 deletions sylvia-derive/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use quote::quote;
use syn::{GenericParam, Ident, ItemImpl, ItemTrait, TraitItem};

use crate::associated_types::{AssociatedTypes, ItemType, EXEC_TYPE, QUERY_TYPE};
use crate::executor::{ContractExecutor, InterfaceExecutor};
use crate::interfaces::Interfaces;
use crate::message::{
ContractApi, ContractEnumMessage, EnumMessage, GlueMessage, InterfaceApi, MsgVariants,
Expand All @@ -15,7 +16,7 @@ use crate::parser::{
assert_new_method_defined, ContractErrorAttr, Custom, OverrideEntryPoint,
ParsedSylviaAttributes,
};
use crate::querier::{ContractQuerier, TraitQuerier};
use crate::querier::{ContractQuerier, InterfaceQuerier};
use crate::variant_descs::AsVariantDescs;

/// Preprocessed `interface` macro input
Expand Down Expand Up @@ -91,10 +92,14 @@ impl<'a> TraitInput<'a> {
let messages = self.emit_messages();
let associated_names: Vec<_> = associated_types.as_filtered_names().collect();

let executor_variants =
MsgVariants::new(item.as_variants(), MsgType::Exec, &associated_names, &None);
let query_variants =
MsgVariants::new(item.as_variants(), MsgType::Query, &associated_names, &None);
let querier =
TraitQuerier::new(&query_variants, associated_types, &item.ident).emit_trait_querier();
let executor = InterfaceExecutor::new(&executor_variants, associated_types, &item.ident)
.emit_executor_trait();
let querier = InterfaceQuerier::new(&query_variants, associated_types, &item.ident)
.emit_querier_trait();

let interface_messages = InterfaceApi::new(item, associated_types, custom).emit();

Expand All @@ -107,6 +112,8 @@ impl<'a> TraitInput<'a> {

#querier

#executor

#interface_messages

#multitest_helpers
Expand Down Expand Up @@ -204,7 +211,20 @@ impl<'a> ImplInput<'a> {
} = self;
let multitest_helpers = self.emit_multitest_helpers();

let querier = ContractQuerier::new(item).emit();
let executor_variants = MsgVariants::new(item.as_variants(), MsgType::Exec, &[], &None);
let querier_variants = MsgVariants::new(item.as_variants(), MsgType::Query, &[], &None);
let executor = ContractExecutor::new(
item.generics.clone(),
*item.self_ty.clone(),
executor_variants,
)
.emit();
let querier = ContractQuerier::new(
item.generics.clone(),
*item.self_ty.clone(),
querier_variants,
)
.emit();
let messages = self.emit_messages();
let contract_api = ContractApi::new(item, generics, custom).emit();

Expand All @@ -218,6 +238,8 @@ impl<'a> ImplInput<'a> {

#querier

#executor

#contract_api
}
}
Expand Down
1 change: 1 addition & 0 deletions sylvia-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use syn::{parse2, parse_quote, ItemImpl, ItemTrait, Path};

mod associated_types;
pub(crate) mod check_generics;
mod executor;
mod input;
mod interfaces;
mod message;
Expand Down
Loading

0 comments on commit 9d62c3c

Please sign in to comment.