Skip to content

Commit

Permalink
fix: Revert removal of , custom parameter support in entry_points m…
Browse files Browse the repository at this point in the history
…acro

Refs: d4c94ca
  • Loading branch information
jawoznia committed Aug 21, 2024
1 parent 2f00961 commit 87b342a
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 50 deletions.
30 changes: 27 additions & 3 deletions sylvia-derive/src/parser/entry_point.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use proc_macro2::TokenStream as TokenStream2;
use proc_macro_error::emit_error;
use syn::parse::{Error, Nothing, Parse, ParseStream};
use proc_macro_error::{emit_error, emit_warning};
use syn::parse::{Error, Nothing, Parse, ParseStream, Parser};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{parse2, GenericArgument, Path, Result, Token};
use syn::{parenthesized, parse2, GenericArgument, Path, Result, Token};

use crate::parser::Custom;

use super::extract_generics_from_path;

Expand Down Expand Up @@ -40,6 +42,28 @@ impl Parse for EntryPointArgs {
_ => return Err(Error::new(generics.span(), "Expected `generics`.")),
};

let comma: Option<Token![,]> = input.parse().ok();
if comma.is_some() {
emit_warning!(
comma.span(), "Deprecated `, custom(msg=.., query=..)` found.";
note = "You can safely remove this parameter as `entry_points` macro does not require it anymore."
);

// Parse custom attribute to not break semver
let custom: Option<Path> = input.parse().ok();
match custom {
Some(custom)
if custom.get_ident().map(|custom| custom.to_string())
== Some("custom".to_owned()) =>
{
let content;
parenthesized!(content in input);
let _ = Custom::parse.parse2(content.parse()?);
}
_ => (),
};
}

let _: Nothing = input.parse()?;

Ok(entry_points_args)
Expand Down
4 changes: 4 additions & 0 deletions sylvia/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,10 @@ pub trait CustomQuery: cosmwasm_std::CustomQuery + DeserializeOwned + JsonSchema
impl<T> CustomQuery for T where T: cosmwasm_std::CustomQuery + DeserializeOwned + JsonSchema {}

/// Api trait for easier access to generated types and messages.
#[deprecated(
since = "1.2.1",
note = "InterfaceApi will be removed in 2.0.0. Please use generated sv::InterfaceMessagesApi instead."
)]
pub trait InterfaceApi {
type Exec;
type Query;
Expand Down
134 changes: 87 additions & 47 deletions sylvia/tests/interface_impl.rs
Original file line number Diff line number Diff line change
@@ -1,138 +1,178 @@
use cosmwasm_std::{Response, StdError, StdResult};
use sylvia::types::{ExecCtx, InstantiateCtx, QueryCtx, SudoCtx};
use cosmwasm_std::{Empty, Response, StdError, StdResult};
use sylvia::types::{CustomMsg, CustomQuery, ExecCtx, InstantiateCtx, QueryCtx, SudoCtx};
use sylvia::{contract, entry_points};

mod interface1 {
use cosmwasm_std::{Response, StdError, StdResult};
use sylvia::interface;
use sylvia::types::{ExecCtx, QueryCtx, SudoCtx};
use sylvia::types::{CustomMsg, CustomQuery, ExecCtx, QueryCtx, SudoCtx};

#[interface]
#[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
pub trait SylviaInterface1 {
type Error: From<StdError>;
type ExecC: CustomMsg;
type QueryC: CustomQuery;

#[sv::msg(exec)]
fn interface1_method_exec(&self, _ctx: ExecCtx) -> StdResult<Response>;
fn interface1_method_exec(
&self,
_ctx: ExecCtx<Self::QueryC>,
) -> StdResult<Response<Self::ExecC>>;

#[sv::msg(query)]
fn interface1_method_query(&self, _ctx: QueryCtx) -> StdResult<Response>;
fn interface1_method_query(
&self,
_ctx: QueryCtx<Self::QueryC>,
) -> StdResult<Response<Self::ExecC>>;

#[sv::msg(sudo)]
fn interface1_method_sudo(&self, _ctx: SudoCtx) -> StdResult<Response>;
fn interface1_method_sudo(
&self,
_ctx: SudoCtx<Self::QueryC>,
) -> StdResult<Response<Self::ExecC>>;
}
}

mod interface2 {
use cosmwasm_std::{Response, StdError, StdResult};
use sylvia::interface;
use sylvia::types::{ExecCtx, QueryCtx, SudoCtx};
use sylvia::types::{CustomMsg, CustomQuery, ExecCtx, QueryCtx, SudoCtx};

#[interface]
#[sv::custom(msg=cosmwasm_std::Empty, query=cosmwasm_std::Empty)]
pub trait SylviaInterface2 {
type Error: From<StdError>;
type ExecC: CustomMsg;
type QueryC: CustomQuery;

#[sv::msg(exec)]
fn interface2_method_exec(&self, _ctx: ExecCtx) -> StdResult<Response>;
fn interface2_method_exec(
&self,
_ctx: ExecCtx<Self::QueryC>,
) -> StdResult<Response<Self::ExecC>>;

#[sv::msg(query)]
fn interface2_method_query(&self, _ctx: QueryCtx) -> StdResult<Response>;
fn interface2_method_query(
&self,
_ctx: QueryCtx<Self::QueryC>,
) -> StdResult<Response<Self::ExecC>>;

#[sv::msg(sudo)]
fn interface2_method_sudo(&self, _ctx: SudoCtx) -> StdResult<Response>;
fn interface2_method_sudo(
&self,
_ctx: SudoCtx<Self::QueryC>,
) -> StdResult<Response<Self::ExecC>>;
}
}

pub struct Contract;
pub struct Contract<E, Q> {
_phantom: std::marker::PhantomData<(E, Q)>,
}

#[entry_points]
// Check that the macro expansion won't fail due to deprecated `, custom` parameter.
#[entry_points(generics<Empty, Empty>, custom(msg=Empty, query=Empty))]
#[contract]
#[sv::messages(interface1)]
#[sv::messages(interface2)]
impl Contract {
#[sv::custom(msg=E, query=Q)]
impl<E, Q> Contract<E, Q>
where
E: CustomMsg + 'static,
Q: CustomQuery + 'static,
{
pub fn new() -> Self {
Self
Self {
_phantom: Default::default(),
}
}

#[sv::msg(instantiate)]
fn instantiate(&self, _ctx: InstantiateCtx) -> StdResult<Response> {
fn instantiate(&self, _ctx: InstantiateCtx<Q>) -> StdResult<Response<E>> {
Ok(Response::new())
}

#[sv::msg(exec)]
fn contract_method_exec(&self, _ctx: ExecCtx) -> StdResult<Response> {
fn contract_method_exec(&self, _ctx: ExecCtx<Q>) -> StdResult<Response<E>> {
Ok(Response::new())
}

#[sv::msg(query)]
fn contract_method_query(&self, _ctx: QueryCtx) -> StdResult<Response> {
fn contract_method_query(&self, _ctx: QueryCtx<Q>) -> StdResult<Response<E>> {
Ok(Response::new())
}

#[sv::msg(sudo)]
fn contract_method_sudo(&self, _ctx: SudoCtx) -> StdResult<Response> {
fn contract_method_sudo(&self, _ctx: SudoCtx<Q>) -> StdResult<Response<E>> {
Ok(Response::new())
}
}

impl interface1::SylviaInterface1 for Contract {
impl<E, Q> interface1::SylviaInterface1 for Contract<E, Q>
where
E: CustomMsg + 'static,
Q: CustomQuery + 'static,
{
type Error = StdError;
type ExecC = E;
type QueryC = Q;

fn interface1_method_exec(&self, _ctx: ExecCtx) -> StdResult<Response> {
fn interface1_method_exec(&self, _ctx: ExecCtx<Q>) -> StdResult<Response<E>> {
Ok(Response::new())
}

fn interface1_method_query(&self, _ctx: QueryCtx) -> StdResult<Response> {
fn interface1_method_query(&self, _ctx: QueryCtx<Q>) -> StdResult<Response<E>> {
Ok(Response::new())
}

fn interface1_method_sudo(&self, _ctx: SudoCtx) -> StdResult<Response> {
fn interface1_method_sudo(&self, _ctx: SudoCtx<Q>) -> StdResult<Response<E>> {
Ok(Response::new())
}
}

impl interface2::SylviaInterface2 for Contract {
impl<E, Q> interface2::SylviaInterface2 for Contract<E, Q>
where
E: CustomMsg + 'static,
Q: CustomQuery + 'static,
{
type Error = StdError;
type ExecC = E;
type QueryC = Q;

fn interface2_method_exec(&self, _ctx: ExecCtx) -> StdResult<Response> {
fn interface2_method_exec(&self, _ctx: ExecCtx<Q>) -> StdResult<Response<E>> {
Ok(Response::new())
}

fn interface2_method_query(&self, _ctx: QueryCtx) -> StdResult<Response> {
fn interface2_method_query(&self, _ctx: QueryCtx<Q>) -> StdResult<Response<E>> {
Ok(Response::new())
}

fn interface2_method_sudo(&self, _ctx: SudoCtx) -> StdResult<Response> {
fn interface2_method_sudo(&self, _ctx: SudoCtx<Q>) -> StdResult<Response<E>> {
Ok(Response::new())
}
}

impl Default for Contract {
fn default() -> Self {
Self::new()
}
}

#[test]
fn check_from_trait_implementations() {
let _ =
sv::ContractExecMsg::from(interface1::sv::SylviaInterface1ExecMsg::Interface1MethodExec {});
let _ = sv::ContractQueryMsg::from(
let _ = sv::ContractExecMsg::<Empty, Empty>::from(
interface1::sv::SylviaInterface1ExecMsg::Interface1MethodExec {},
);
let _ = sv::ContractQueryMsg::<Empty, Empty>::from(
interface1::sv::SylviaInterface1QueryMsg::Interface1MethodQuery {},
);
let _ =
sv::ContractSudoMsg::from(interface1::sv::SylviaInterface1SudoMsg::Interface1MethodSudo {});
let _ = sv::ContractSudoMsg::<Empty, Empty>::from(
interface1::sv::SylviaInterface1SudoMsg::Interface1MethodSudo {},
);

let _ =
sv::ContractExecMsg::from(interface2::sv::SylviaInterface2ExecMsg::Interface2MethodExec {});
let _ = sv::ContractQueryMsg::from(
let _ = sv::ContractExecMsg::<Empty, Empty>::from(
interface2::sv::SylviaInterface2ExecMsg::Interface2MethodExec {},
);
let _ = sv::ContractQueryMsg::<Empty, Empty>::from(
interface2::sv::SylviaInterface2QueryMsg::Interface2MethodQuery {},
);
let _ =
sv::ContractSudoMsg::from(interface2::sv::SylviaInterface2SudoMsg::Interface2MethodSudo {});
let _ = sv::ContractSudoMsg::<Empty, Empty>::from(
interface2::sv::SylviaInterface2SudoMsg::Interface2MethodSudo {},
);

let _ = sv::ContractExecMsg::from(sv::ExecMsg::ContractMethodExec {});
let _ = sv::ContractQueryMsg::from(sv::QueryMsg::ContractMethodQuery {});
let _ = sv::ContractSudoMsg::from(sv::SudoMsg::ContractMethodSudo {});
let _ = sv::ContractExecMsg::<Empty, Empty>::from(sv::ExecMsg::ContractMethodExec {});
let _ = sv::ContractQueryMsg::<Empty, Empty>::from(sv::QueryMsg::ContractMethodQuery {});
let _ = sv::ContractSudoMsg::<Empty, Empty>::from(sv::SudoMsg::ContractMethodSudo {});
}

0 comments on commit 87b342a

Please sign in to comment.