Skip to content

Commit

Permalink
feat: Generate SudoMsg in contract
Browse files Browse the repository at this point in the history
  • Loading branch information
jawoznia committed Nov 15, 2023
1 parent 1713606 commit fcc0504
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 35 deletions.
6 changes: 6 additions & 0 deletions sylvia-derive/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,10 @@ impl<'a> ImplInput<'a> {
let migrate = self.emit_struct_msg(MsgType::Migrate);
let exec_impl = self.emit_enum_msg(MsgType::Exec);
let query_impl = self.emit_enum_msg(MsgType::Query);
let sudo_impl = self.emit_enum_msg(MsgType::Sudo);
let exec = self.emit_glue_msg(MsgType::Exec);
let query = self.emit_glue_msg(MsgType::Query);
let sudo = self.emit_glue_msg(MsgType::Sudo);

#[cfg(not(tarpaulin_include))]
{
Expand All @@ -253,11 +255,15 @@ impl<'a> ImplInput<'a> {

#query_impl

#sudo_impl

#migrate

#exec

#query

#sudo
}
}
}
Expand Down
34 changes: 28 additions & 6 deletions sylvia-derive/src/interfaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,17 @@ impl Interfaces {
generics,
..
} = interface;

let generics = if !generics.is_empty() {
quote! { < #generics > }
} else {
quote! {}
};

let interface_enum =
quote! { <#module ::sv::Api #generics as #sylvia ::types::InterfaceApi> };
if msg_ty == &MsgType::Query {
quote! { #variant ( #interface_enum :: Query) }
} else {
quote! { #variant ( #interface_enum :: Exec)}
}
let type_name = msg_ty.as_accessor_name(false);

quote! { #variant ( #interface_enum :: #type_name) }
})
.collect()
}
Expand Down Expand Up @@ -167,6 +165,30 @@ impl Interfaces {
.collect()
}

pub fn emit_dispatch_arms(&self, msg_ty: &MsgType) -> Vec<TokenStream> {
let sylvia = crate_module();
let contract_enum_name = msg_ty.emit_msg_name(true);

self.interfaces.iter().map(|interface| {
let ContractMessageAttr {
variant,
customs,
..
} = interface;

let ctx = msg_ty.emit_ctx_dispatch_values(customs);

match (msg_ty, customs.has_msg) {
(MsgType::Exec, true) | (MsgType::Sudo, true) => quote! {
#contract_enum_name:: #variant(msg) => #sylvia ::into_response::IntoResponse::into_response(msg.dispatch(contract, Into::into( #ctx ))?)
},
_ => quote! {
#contract_enum_name :: #variant(msg) => msg.dispatch(contract, Into::into( #ctx ))
},
}
}).collect()
}

pub fn as_modules(&self) -> impl Iterator<Item = &Path> {
self.interfaces.iter().map(|interface| &interface.module)
}
Expand Down
58 changes: 30 additions & 28 deletions sylvia-derive/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use crate::check_generics::{CheckGenerics, GetPath};
use crate::crate_module;
use crate::interfaces::Interfaces;
use crate::parser::{
parse_associated_custom_type, parse_struct_message, ContractErrorAttr, ContractMessageAttr,
Custom, EntryPointArgs, MsgAttr, MsgType, OverrideEntryPoints,
parse_associated_custom_type, parse_struct_message, ContractErrorAttr, Custom, EntryPointArgs,
MsgAttr, MsgType, OverrideEntryPoints,
};
use crate::strip_generics::StripGenerics;
use crate::utils::{
Expand Down Expand Up @@ -1290,32 +1290,7 @@ impl<'a> GlueMessage<'a> {

let variants_cnt = messages_call.len();

let dispatch_arms = interfaces.interfaces().iter().map(|interface| {
let ContractMessageAttr {
variant,
customs,
..
} = interface;

let ctx = match (msg_ty, customs.has_query) {
(MsgType::Exec, true )=> quote! {
( ctx.0.into_empty(), ctx.1, ctx.2)
},
(MsgType::Query, true )=> quote! {
( ctx.0.into_empty(), ctx.1)
},
_=> quote! { ctx },
};

match (msg_ty, customs.has_msg) {
(MsgType::Exec, true) => quote! {
#contract_enum_name:: #variant(msg) => #sylvia ::into_response::IntoResponse::into_response(msg.dispatch(contract, Into::into( #ctx ))?)
},
_ => quote! {
#contract_enum_name :: #variant(msg) => msg.dispatch(contract, Into::into( #ctx ))
},
}
});
let dispatch_arms = interfaces.emit_dispatch_arms(msg_ty);

let dispatch_arm =
quote! {#contract_enum_name :: #contract_name (msg) => msg.dispatch(contract, ctx)};
Expand Down Expand Up @@ -1439,6 +1414,7 @@ pub struct ContractApi<'a> {
query_variants: MsgVariants<'a, GenericParam>,
instantiate_variants: MsgVariants<'a, GenericParam>,
migrate_variants: MsgVariants<'a, GenericParam>,
sudo_variants: MsgVariants<'a, GenericParam>,
generics: &'a [&'a GenericParam],
custom: &'a Custom<'a>,
}
Expand Down Expand Up @@ -1477,12 +1453,20 @@ impl<'a> ContractApi<'a> {
&source.generics.where_clause,
);

let sudo_variants = MsgVariants::new(
source.as_variants(),
MsgType::Sudo,
generics,
&source.generics.where_clause,
);

Self {
source,
exec_variants,
query_variants,
instantiate_variants,
migrate_variants,
sudo_variants,
generics,
custom,
}
Expand All @@ -1496,6 +1480,7 @@ impl<'a> ContractApi<'a> {
query_variants,
instantiate_variants,
migrate_variants,
sudo_variants,
generics,
custom,
} = self;
Expand All @@ -1505,12 +1490,14 @@ impl<'a> ContractApi<'a> {
let query_generics = &query_variants.used_generics;
let instantiate_generics = &instantiate_variants.used_generics;
let migrate_generics = &migrate_variants.used_generics;
let sudo_generics = &sudo_variants.used_generics;

let bracket_generics = emit_bracketed_generics(generics);
let exec_bracketed_generics = emit_bracketed_generics(exec_generics);
let query_bracketed_generics = emit_bracketed_generics(query_generics);
let instantiate_bracketed_generics = emit_bracketed_generics(instantiate_generics);
let migrate_bracketed_generics = emit_bracketed_generics(migrate_generics);
let sudo_bracketed_generics = emit_bracketed_generics(sudo_generics);

let migrate_type = match !migrate_variants.variants().is_empty() {
true => quote! { type Migrate = MigrateMsg #migrate_bracketed_generics; },
Expand All @@ -1522,8 +1509,10 @@ impl<'a> ContractApi<'a> {
impl #bracket_generics #sylvia ::types::ContractApi for #contract_name {
type ContractExec = ContractExecMsg #exec_bracketed_generics;
type ContractQuery = ContractQueryMsg #query_bracketed_generics;
type ContractSudo = ContractSudoMsg #sudo_bracketed_generics;
type Exec = ExecMsg #exec_bracketed_generics;
type Query = QueryMsg #query_bracketed_generics;
type Sudo = SudoMsg #sudo_bracketed_generics;
type Instantiate = InstantiateMsg #instantiate_bracketed_generics;
#migrate_type
type Remote<'remote> = Remote<'remote>;
Expand All @@ -1536,6 +1525,7 @@ impl<'a> ContractApi<'a> {
pub struct InterfaceApi<'a> {
exec_variants: MsgVariants<'a, GenericParam>,
query_variants: MsgVariants<'a, GenericParam>,
sudo_variants: MsgVariants<'a, GenericParam>,
generics: &'a [&'a GenericParam],
}

Expand All @@ -1555,9 +1545,17 @@ impl<'a> InterfaceApi<'a> {
&source.generics.where_clause,
);

let sudo_variants = MsgVariants::new(
source.as_variants(),
MsgType::Sudo,
generics,
&source.generics.where_clause,
);

Self {
exec_variants,
query_variants,
sudo_variants,
generics,
}
}
Expand All @@ -1567,15 +1565,18 @@ impl<'a> InterfaceApi<'a> {
let Self {
exec_variants,
query_variants,
sudo_variants,
generics,
} = self;

let exec_generics = &exec_variants.used_generics;
let query_generics = &query_variants.used_generics;
let sudo_generics = &sudo_variants.used_generics;

let bracket_generics = emit_bracketed_generics(generics);
let exec_bracketed_generics = emit_bracketed_generics(exec_generics);
let query_bracketed_generics = emit_bracketed_generics(query_generics);
let sudo_bracketed_generics = emit_bracketed_generics(sudo_generics);

let phantom = if !generics.is_empty() {
quote! {
Expand All @@ -1593,6 +1594,7 @@ impl<'a> InterfaceApi<'a> {
impl #bracket_generics #sylvia ::types::InterfaceApi for Api #bracket_generics {
type Exec = ExecMsg #exec_bracketed_generics;
type Query = QueryMsg #query_bracketed_generics;
type Sudo = SudoMsg #sudo_bracketed_generics;
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions sylvia-derive/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,20 @@ impl MsgType {
}
}

pub fn emit_ctx_dispatch_values(self, customs: &Customs) -> TokenStream {
use MsgType::*;

match (self, customs.has_query) {
(Exec, true) => quote! {
(ctx.0.into_empty(), ctx.1, ctx.2)
},
(Query, true) | (Sudo, true) => quote! {
(ctx.0.into_empty(), ctx.1)
},
_ => quote! { ctx },
}
}

/// Emits type which should be returned by dispatch function for this kind of message
pub fn emit_result_type(self, msg_type: &Type, err_type: &Type) -> TokenStream {
use MsgType::*;
Expand All @@ -176,6 +190,7 @@ impl MsgType {
match self {
MsgType::Exec if is_wrapper => parse_quote! { ContractExecMsg },
MsgType::Query if is_wrapper => parse_quote! { ContractQueryMsg },
MsgType::Sudo if is_wrapper => parse_quote! { ContractSudoMsg },
MsgType::Exec => parse_quote! { ExecMsg },
MsgType::Query => parse_quote! { QueryMsg },
MsgType::Instantiate => parse_quote! { InstantiateMsg },
Expand All @@ -189,6 +204,7 @@ impl MsgType {
match self {
MsgType::Exec if is_wrapper => Some(parse_quote! { ContractExec }),
MsgType::Query if is_wrapper => Some(parse_quote! { ContractQuery }),
MsgType::Sudo if is_wrapper => Some(parse_quote! { ContractSudo }),

Check warning on line 207 in sylvia-derive/src/parser.rs

View check run for this annotation

Codecov / codecov/patch

sylvia-derive/src/parser.rs#L207

Added line #L207 was not covered by tests
MsgType::Instantiate => Some(parse_quote! { Instantiate }),
MsgType::Exec => Some(parse_quote! { Exec }),
MsgType::Query => Some(parse_quote! { Query }),
Expand Down
3 changes: 3 additions & 0 deletions sylvia/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ impl cosmwasm_std::CustomMsg for SvCustomMsg {}
pub trait InterfaceApi {
type Exec;
type Query;
type Sudo;
}

pub trait ContractApi {
Expand All @@ -122,7 +123,9 @@ pub trait ContractApi {
type Exec;
type ContractQuery;
type ContractExec;
type ContractSudo;
type Migrate;
type Sudo;
type Querier<'querier>;
type Remote<'remote>;
}
21 changes: 20 additions & 1 deletion sylvia/tests/messages_generation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ mod interface {
mod contract {
use cosmwasm_std::{Addr, Reply, Response, StdResult};
use sylvia::contract;
use sylvia::types::{ExecCtx, InstantiateCtx, MigrateCtx, QueryCtx, ReplyCtx};
use sylvia::types::{ExecCtx, InstantiateCtx, MigrateCtx, QueryCtx, ReplyCtx, SudoCtx};
use sylvia_derive::entry_points;

use crate::{MyQuery, QueryResult};
Expand Down Expand Up @@ -113,6 +113,16 @@ mod contract {
fn my_reply(&self, _ctx: ReplyCtx<MyQuery>, _reply: Reply) -> StdResult<Response> {
Ok(Response::new())
}

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

#[msg(sudo)]
fn argumented_sudo(&self, _ctx: SudoCtx<MyQuery>, _user: Addr) -> StdResult<Response> {
Ok(Response::new())
}
}
}

Expand Down Expand Up @@ -162,6 +172,10 @@ fn contract_messages_constructible() {
let _argumented_query = contract::sv::QueryMsg::ArgumentedQuery {
_user: Addr::unchecked("owner"),
};
let no_args_sudo = contract::sv::SudoMsg::NoArgsSudo {};
let _ = contract::sv::SudoMsg::ArgumentedSudo {
_user: Addr::unchecked("owner"),
};
let _ = contract::sv::InstantiateMsg {};
let _ = contract::sv::MigrateMsg {};

Expand All @@ -175,6 +189,11 @@ fn contract_messages_constructible() {
contract::sv::QueryMsg::NoArgsQuery {} => (),
contract::sv::QueryMsg::ArgumentedQuery { .. } => (),
}

match no_args_sudo {
contract::sv::SudoMsg::NoArgsSudo {} => (),
contract::sv::SudoMsg::ArgumentedSudo { .. } => (),
}
}

#[test]
Expand Down

0 comments on commit fcc0504

Please sign in to comment.