Skip to content

Commit

Permalink
feat: From implementation for contract messages of interface messag…
Browse files Browse the repository at this point in the history
…es (#391)
  • Loading branch information
kulikthebird committed Jul 9, 2024
1 parent 3ab2a01 commit 4ffbb45
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 1 deletion.
10 changes: 9 additions & 1 deletion sylvia-derive/src/interfaces.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::spanned::Spanned;
use syn::{ItemImpl, Type};
use syn::{ItemImpl, Path, Type};

use crate::crate_module;
use crate::parser::attributes::msg::MsgType;
Expand Down Expand Up @@ -133,4 +133,12 @@ impl Interfaces {
}
}).collect()
}

pub fn variants_names(&self) -> impl Iterator<Item = &Ident> {
self.interfaces.iter().map(|interface| &interface.variant)
}

pub fn variants_modules(&self) -> impl Iterator<Item = &Path> {
self.interfaces.iter().map(|interface| &interface.module)
}
}
19 changes: 19 additions & 0 deletions sylvia-derive/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,9 @@ impl<'a> GlueMessage<'a> {
}
};

let modules_names = interfaces.variants_modules();
let variants_names = interfaces.variants_names();

quote! {
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(#sylvia ::serde::Serialize, Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -1058,6 +1061,22 @@ impl<'a> GlueMessage<'a> {
Err(D::Error::custom(err_msg))
}
}

impl #bracketed_wrapper_generics From<<#contract as #sylvia ::types::ContractApi>:: #enum_accessor>
for #contract_enum_name #bracketed_wrapper_generics #full_where_clause {
fn from(a: <#contract as #sylvia ::types::ContractApi>:: #enum_accessor ) -> Self {
Self:: #contract_name (a)
}
}

#(
impl #bracketed_wrapper_generics From<<#contract as #modules_names ::sv::InterfaceMessagesApi>:: #enum_accessor>
for #contract_enum_name #bracketed_wrapper_generics #full_where_clause {
fn from(a: <#contract as #modules_names ::sv::InterfaceMessagesApi>:: #enum_accessor ) -> Self {
Self:: #variants_names (a)
}
}
)*
}
}
}
Expand Down
137 changes: 137 additions & 0 deletions sylvia/tests/interface_impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
use cosmwasm_std::{Response, StdError, StdResult};
use sylvia::contract;
use sylvia::types::{ExecCtx, InstantiateCtx, QueryCtx, SudoCtx};

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

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

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

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

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

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

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

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

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

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

pub struct Contract;

#[contract]
#[sv::messages(interface1)]
#[sv::messages(interface2)]
impl Contract {
pub fn new() -> Self {
Self
}

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

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

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

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

impl interface1::SylviaInterface1 for Contract {
type Error = StdError;

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

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

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

impl interface2::SylviaInterface2 for Contract {
type Error = StdError;

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

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

fn interface2_method_sudo(&self, _ctx: SudoCtx) -> StdResult<Response> {
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(
interface1::sv::SylviaInterface1QueryMsg::Interface1MethodQuery {},
);
let _ =
sv::ContractSudoMsg::from(interface1::sv::SylviaInterface1SudoMsg::Interface1MethodSudo {});

let _ =
sv::ContractExecMsg::from(interface2::sv::SylviaInterface2ExecMsg::Interface2MethodExec {});
let _ = sv::ContractQueryMsg::from(
interface2::sv::SylviaInterface2QueryMsg::Interface2MethodQuery {},
);
let _ =
sv::ContractSudoMsg::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 {});
}

0 comments on commit 4ffbb45

Please sign in to comment.