Skip to content

Commit

Permalink
Merge pull request #127 from CosmWasm/bound_querier_conversion
Browse files Browse the repository at this point in the history
Bound querier conversion
  • Loading branch information
jawoznia committed May 24, 2023
2 parents 46cc1c2 + 1a8a4c1 commit caf64a0
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 4 deletions.
4 changes: 4 additions & 0 deletions sylvia-derive/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use syn::spanned::Spanned;
use syn::{parse_quote, GenericParam, Ident, ItemImpl, ItemTrait, TraitItem, Type};

use crate::crate_module;
use crate::interfaces::Interfaces;
use crate::message::{ContractEnumMessage, EnumMessage, GlueMessage, MsgVariants, StructMessage};
use crate::multitest::{MultitestHelpers, TraitMultitestHelpers};
use crate::parser::{ContractArgs, ContractErrorAttr, InterfaceArgs, MsgType};
Expand Down Expand Up @@ -172,6 +173,7 @@ impl<'a> ImplInput<'a> {
let messages = self.emit_messages();
let remote = Remote::new(&self.item.attrs).emit();
let querier = MsgVariants::new(self.item.as_variants(), &self.generics).emit_querier();
let querier_from_impl = Interfaces::new(self.item).emit_querier_from_impl();

#[cfg(not(tarpaulin_include))]
let code = quote! {
Expand All @@ -182,6 +184,8 @@ impl<'a> ImplInput<'a> {
#remote

#querier

#(#querier_from_impl)*
};

if let Some(module) = &self.attributes.module {
Expand Down
54 changes: 54 additions & 0 deletions sylvia-derive/src/interfaces.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use proc_macro2::TokenStream;
use proc_macro_error::emit_error;
use quote::quote;
use syn::parse::{Parse, Parser};
use syn::spanned::Spanned;
use syn::ItemImpl;

use crate::crate_module;
use crate::parser::ContractMessageAttr;

pub struct Interfaces {
interfaces: Vec<ContractMessageAttr>,
}

impl Interfaces {
pub fn new(source: &ItemImpl) -> Self {
let interfaces: Vec<_> = source
.attrs
.iter()
.filter(|attr| attr.path.is_ident("messages"))
.filter_map(|attr| {
let interface = match ContractMessageAttr::parse.parse2(attr.tokens.clone()) {
Ok(interface) => interface,
Err(err) => {
emit_error!(attr.span(), err);
return None;
}
};

Some(interface)
})
.collect();

Self { interfaces }
}

pub fn emit_querier_from_impl(&self) -> Vec<TokenStream> {
let sylvia = crate_module();

self.interfaces
.iter()
.map(|interface| {
let ContractMessageAttr { module, .. } = interface;
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 {
Self::borrowed(querier.contract(), querier.querier())
}
}
}
})
.collect()
}
}
1 change: 1 addition & 0 deletions sylvia-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use syn::{parse2, parse_quote, ItemImpl, ItemTrait, Path};

pub(crate) mod check_generics;
mod input;
mod interfaces;
mod message;
mod multitest;
mod parser;
Expand Down
14 changes: 14 additions & 0 deletions sylvia-derive/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,20 @@ impl<'a> MsgVariants<'a> {
querier: &'a #sylvia ::cw_std::QuerierWrapper<'a, C>,
}

impl<'a, C: #sylvia ::cw_std::CustomQuery> BoundQuerier<'a, C> {
pub fn querier(&self) -> &'a #sylvia ::cw_std::QuerierWrapper<'a, C> {
self.querier
}

pub fn contract(&self) -> &'a #sylvia ::cw_std::Addr {
self.contract
}

pub fn borrowed(contract: &'a #sylvia ::cw_std::Addr, querier: &'a #sylvia ::cw_std::QuerierWrapper<'a, C>) -> Self {
Self {contract, querier}
}
}

impl <'a, C: #sylvia ::cw_std::CustomQuery> Querier for BoundQuerier<'a, C> {
#(#methods_impl)*
}
Expand Down
2 changes: 1 addition & 1 deletion sylvia-derive/src/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl Remote {
}

impl Remote<'_> {
fn querier<'a, C: #sylvia ::cw_std::CustomQuery>(&'a self, querier: &'a #sylvia ::cw_std::QuerierWrapper<'a, C>) -> BoundQuerier<'a, C> {
pub fn querier<'a, C: #sylvia ::cw_std::CustomQuery>(&'a self, querier: &'a #sylvia ::cw_std::QuerierWrapper<'a, C>) -> BoundQuerier<'a, C> {
BoundQuerier {
contract: &self.0,
querier,
Expand Down
53 changes: 50 additions & 3 deletions sylvia/tests/querier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ pub mod counter {

#[msg(exec)]
fn set_count(&self, ctx: ExecCtx, new_count: u64) -> StdResult<Response>;

#[msg(exec)]
fn decrease_by_count(&self, ctx: ExecCtx) -> StdResult<Response>;
}

#[contract]
Expand All @@ -50,11 +53,25 @@ pub mod counter {
#[msg(exec)]
fn copy_count(&self, ctx: ExecCtx) -> StdResult<Response> {
let remote = self.remote.load(ctx.deps.storage)?;
let remote = Remote::from(&remote);
let other_count = remote.querier(&ctx.deps.querier).count()?.count;
let querier = remote.querier(&ctx.deps.querier);
let other_count = BoundQuerier::from(&querier).count()?.count;
self.count.save(ctx.deps.storage, &other_count)?;
Ok(Response::new())
}

#[msg(exec)]
fn decrease_by_count(&self, ctx: ExecCtx) -> StdResult<Response> {
let remote = self.remote.load(ctx.deps.storage)?;
let other_count = BoundQuerier::borrowed(&remote.0, &ctx.deps.querier)
.count()?
.count;
self.count.update(ctx.deps.storage, |count| {
let count = count.saturating_sub(other_count);
Ok::<_, StdError>(count)
})?;

Ok(Response::new())
}
}
}

Expand Down Expand Up @@ -85,12 +102,33 @@ impl CounterContract<'_> {

#[cfg(test)]
mod tests {
use cosmwasm_std::Addr;

use cosmwasm_std::testing::mock_dependencies;
use cosmwasm_std::{Addr, Empty, QuerierWrapper};
use sylvia::multitest::App;

use crate::counter::test_utils::Counter;
use crate::multitest_utils::CodeId;

#[test]
fn querier_generation() {
let deps = mock_dependencies();
let querier_wrapper = QuerierWrapper::<Empty>::new(&deps.querier);
let remote_addr = Addr::unchecked("remote");

// Remote generation
let remote = super::counter::Remote::new(remote_addr.clone());
let _: super::counter::BoundQuerier<_> = remote.querier(&querier_wrapper);
let remote = super::Remote::new(remote_addr.clone());
let _: super::BoundQuerier<_> = remote.querier(&querier_wrapper);

// Querier generation
let _ = super::counter::BoundQuerier::borrowed(&remote_addr, &querier_wrapper);
let querier = super::BoundQuerier::borrowed(&remote_addr, &querier_wrapper);

let _ = super::counter::BoundQuerier::from(&querier);
}

#[test]
fn call_querier() {
let app = App::default();
Expand Down Expand Up @@ -127,5 +165,14 @@ mod tests {

let resp = second_contract.counter_proxy().count().unwrap();
assert_eq!(resp.count, 42);

second_contract
.counter_proxy()
.decrease_by_count()
.call(owner)
.unwrap();

let resp = second_contract.counter_proxy().count().unwrap();
assert_eq!(resp.count, 0);
}
}

0 comments on commit caf64a0

Please sign in to comment.