Skip to content

Commit

Permalink
fix: Prefix interface proxy with module as Path
Browse files Browse the repository at this point in the history
  • Loading branch information
jawoznia committed Aug 11, 2023
1 parent ec8b947 commit 596f682
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 188 deletions.
18 changes: 15 additions & 3 deletions sylvia-derive/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub struct ImplInput<'a> {
generics: Vec<&'a GenericParam>,
custom: Custom<'a>,
override_entry_points: OverrideEntryPoints,
interfaces: Interfaces,
}

impl<'a> TraitInput<'a> {
Expand Down Expand Up @@ -60,7 +61,7 @@ impl<'a> TraitInput<'a> {
pub fn process(&self) -> TokenStream {
let messages = self.emit_messages();
let multitest_helpers = self.emit_helpers();
let remote = Remote::new(&[]).emit();
let remote = Remote::new(&Interfaces::default()).emit();
let querier = MsgVariants::new(self.item.as_variants(), &self.generics).emit_querier();

#[cfg(not(tarpaulin_include))]
Expand Down Expand Up @@ -128,6 +129,7 @@ impl<'a> ImplInput<'a> {

let custom = Custom::new(&item.attrs);
let override_entry_points = OverrideEntryPoints::new(&item.attrs);
let interfaces = Interfaces::new(item);

Self {
attributes,
Expand All @@ -136,6 +138,7 @@ impl<'a> ImplInput<'a> {
error,
custom,
override_entry_points,
interfaces,
}
}

Expand All @@ -149,6 +152,7 @@ impl<'a> ImplInput<'a> {
&self.generics,
&self.custom,
&self.override_entry_points,
&self.interfaces,
)
.emit()
} else {
Expand Down Expand Up @@ -187,7 +191,7 @@ impl<'a> ImplInput<'a> {
multitest_helpers: TokenStream,
) -> TokenStream {
let messages = self.emit_messages();
let remote = Remote::new(&self.item.attrs).emit();
let remote = Remote::new(interfaces).emit();
let querier = variants.emit_querier();
let querier_from_impl = interfaces.emit_querier_from_impl();

Expand Down Expand Up @@ -252,7 +256,15 @@ impl<'a> ImplInput<'a> {
}

fn emit_glue_msg(&self, name: &Ident, msg_ty: MsgType) -> TokenStream {
GlueMessage::new(name, self.item, msg_ty, &self.error, &self.custom).emit()
GlueMessage::new(
name,
self.item,
msg_ty,
&self.error,
&self.custom,
&self.interfaces,
)
.emit()
}

fn emit_querier_for_bound_impl(
Expand Down
117 changes: 110 additions & 7 deletions sylvia-derive/src/interfaces.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
use proc_macro2::TokenStream;
use convert_case::{Case, Casing};
use proc_macro2::{Ident, TokenStream};
use proc_macro_error::emit_error;
use quote::quote;
use syn::parse::{Parse, Parser};
use syn::spanned::Spanned;
use syn::ItemImpl;
use syn::{ItemImpl, Path, Type};

use crate::crate_module;
use crate::parser::ContractMessageAttr;
use crate::parser::{ContractMessageAttr, MsgType};

#[derive(Debug, Default)]
pub struct Interfaces {
interfaces: Vec<ContractMessageAttr>,
}

impl Interfaces {
fn merge_module_with_name(message_attr: &ContractMessageAttr, name: &syn::Ident) -> syn::Ident {
// ContractMessageAttr will fail to parse empty `#[messsages()]` attribute so we can safely unwrap here
let syn::PathSegment { ident, .. } = &message_attr.module.segments.last().unwrap();
let module_name = ident.to_string().to_case(Case::UpperCamel);
syn::Ident::new(&format!("{}{}", module_name, name), name.span())
}

pub fn new(source: &ItemImpl) -> Self {
let interfaces: Vec<_> = source
.attrs
Expand Down Expand Up @@ -41,10 +50,8 @@ impl Interfaces {
pub fn emit_querier_from_impl(&self) -> Vec<TokenStream> {
let sylvia = crate_module();

self.interfaces
.iter()
.map(|interface| {
let ContractMessageAttr { module, .. } = interface;
self.as_modules()
.map(|module| {
quote! {
impl<'a, C: #sylvia ::cw_std::CustomQuery> From<&'a BoundQuerier<'a, C>> for #module ::BoundQuerier<'a, C> {
fn from(querier: &'a BoundQuerier<'a, C>) -> Self {
Expand All @@ -55,4 +62,100 @@ impl Interfaces {
})
.collect()
}

pub fn emit_proxy_accessors(&self, mt_app: &Type) -> Vec<TokenStream> {
self.as_modules()
.map(|module| {
// ContractMessageAttr will fail to parse empty `#[messsages()]` attribute so we can safely unwrap here
let module_name = &module.segments.last().unwrap().ident;
let method_name = Ident::new(&format!("{}_proxy", module_name), module_name.span());
let proxy_name = Ident::new(
&format!("{}Proxy", module_name.to_string().to_case(Case::UpperCamel)),
module_name.span(),
);

quote! {
pub fn #method_name (&self) -> #module ::trait_utils:: #proxy_name <'app, #mt_app> {
#module ::trait_utils:: #proxy_name ::new(self.contract_addr.clone(), self.app)
}
}
})
.collect()
}

pub fn emit_glue_message_variants(
&self,
msg_ty: &MsgType,
msg_name: &Ident,
) -> Vec<TokenStream> {
self.interfaces
.iter()
.map(|interface| {
let ContractMessageAttr {
module,
exec_generic_params,
query_generic_params,
variant,
..
} = interface;

let generics = match msg_ty {
MsgType::Exec => exec_generic_params.as_slice(),
MsgType::Query => query_generic_params.as_slice(),
_ => &[],

Check warning on line 105 in sylvia-derive/src/interfaces.rs

View check run for this annotation

Codecov / codecov/patch

sylvia-derive/src/interfaces.rs#L105

Added line #L105 was not covered by tests
};

let enum_name = Self::merge_module_with_name(interface, msg_name);
quote! { #variant(#module :: #enum_name<#(#generics,)*>) }
})
.collect()
}

pub fn emit_messages_call(&self, msg_name: &Ident) -> Vec<TokenStream> {
self.interfaces
.iter()
.map(|interface| {
let enum_name = Self::merge_module_with_name(interface, msg_name);
let module = &interface.module;
quote! { &#module :: #enum_name :: messages()}
})
.collect()
}

pub fn emit_deserialization_attempts(&self, msg_name: &Ident) -> Vec<TokenStream> {
self.interfaces
.iter()
.map(|interface| {
let ContractMessageAttr {
module, variant, ..
} = interface;
let enum_name = Self::merge_module_with_name(interface, msg_name);

quote! {
let msgs = &#module :: #enum_name ::messages();
if msgs.into_iter().any(|msg| msg == &recv_msg_name) {
match val.deserialize_into() {
Ok(msg) => return Ok(Self:: #variant (msg)),
Err(err) => return Err(D::Error::custom(err)).map(Self:: #variant),
};
}
}
})
.collect()
}

pub fn emit_response_schemas_calls(&self, msg_name: &Ident) -> Vec<TokenStream> {
self.interfaces
.iter()
.map(|interface| {
let enum_name = Self::merge_module_with_name(interface, msg_name);
let module = &interface.module;
quote! { #module :: #enum_name :: response_schemas_impl()}
})
.collect()
}

pub fn as_modules(&self) -> impl Iterator<Item = &Path> {
self.interfaces.iter().map(|interface| &interface.module)
}
}
Loading

0 comments on commit 596f682

Please sign in to comment.