Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Generate SudoMsg in interface #255

Merged
merged 1 commit into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions sylvia-derive/src/input.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use proc_macro2::{Span, TokenStream};
use proc_macro2::TokenStream;
use proc_macro_error::emit_error;
use quote::{quote, ToTokens};
use syn::parse::{Parse, Parser};
Expand Down Expand Up @@ -109,21 +109,24 @@ impl<'a> TraitInput<'a> {
}

fn emit_messages(&self) -> TokenStream {
let exec = self.emit_msg(&Ident::new("ExecMsg", Span::mixed_site()), MsgType::Exec);
let query = self.emit_msg(&Ident::new("QueryMsg", Span::mixed_site()), MsgType::Query);
let exec = self.emit_msg(MsgType::Exec);
let query = self.emit_msg(MsgType::Query);
let sudo = self.emit_msg(MsgType::Sudo);

#[cfg(not(tarpaulin_include))]
{
quote! {
#exec

#query

#sudo
}
}
}

fn emit_msg(&self, name: &Ident, msg_ty: MsgType) -> TokenStream {
EnumMessage::new(name, self.item, msg_ty, &self.generics, &self.custom).emit()
fn emit_msg(&self, msg_ty: MsgType) -> TokenStream {
EnumMessage::new(self.item, msg_ty, &self.generics, &self.custom).emit()
}
}

Expand Down
21 changes: 9 additions & 12 deletions sylvia-derive/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@

/// Representation of single enum message
pub struct EnumMessage<'a> {
name: &'a Ident,
trait_name: &'a Ident,
variants: Vec<MsgVariant<'a>>,
generics: Vec<&'a GenericParam>,
Expand All @@ -162,7 +161,6 @@

impl<'a> EnumMessage<'a> {
pub fn new(
name: &'a Ident,
source: &'a ItemTrait,
ty: MsgType,
generics: &'a [&'a GenericParam],
Expand Down Expand Up @@ -212,7 +210,6 @@
let wheres = filter_wheres(&source.generics.where_clause, generics, &used_generics);

Self {
name,
trait_name,
variants,
generics: used_generics,
Expand All @@ -230,7 +227,6 @@
let sylvia = crate_module();

let Self {
name,
trait_name,
variants,
generics,
Expand All @@ -243,6 +239,7 @@
query_type,
} = self;

let msg_name = msg_ty.emit_msg_name(false);
let match_arms = variants.iter().map(|variant| variant.emit_dispatch_leg());
let mut msgs: Vec<String> = variants
.iter()
Expand Down Expand Up @@ -292,13 +289,13 @@

let generics = emit_bracketed_generics(generics);

let unique_enum_name = Ident::new(&format!("{}{}", trait_name, name), name.span());
let unique_enum_name = Ident::new(&format!("{}{}", trait_name, msg_name), msg_name.span());

let ep_name = msg_ty.emit_ep_name();
let messages_fn_name = Ident::new(&format!("{}_messages", ep_name), name.span());
let messages_fn_name = Ident::new(&format!("{}_messages", ep_name), msg_name.span());

#[cfg(not(tarpaulin_include))]
let enum_declaration = match name.to_string().as_str() {
let enum_declaration = match msg_name.to_string().as_str() {
"QueryMsg" => {
quote! {
#[allow(clippy::derive_partial_eq_without_eq)]
Expand All @@ -308,7 +305,7 @@
#(#variants,)*
#phantom
}
pub type #name #generics = #unique_enum_name #generics;
pub type #msg_name #generics = #unique_enum_name #generics;
}
}
_ => {
Expand All @@ -320,7 +317,7 @@
#(#variants,)*
#phantom
}
pub type #name #generics = #unique_enum_name #generics;
pub type #msg_name #generics = #unique_enum_name #generics;
}
}
};
Expand Down Expand Up @@ -562,7 +559,7 @@

#[cfg(not(tarpaulin_include))]
match msg_type {
Exec => quote! {
Exec | Sudo => quote! {
#name {
#(#fields,)*
} => contract.#function_name(Into::into(ctx), #(#args),*).map_err(Into::into)
Expand All @@ -572,8 +569,8 @@
#(#fields,)*
} => #sylvia ::cw_std::to_binary(&contract.#function_name(Into::into(ctx), #(#args),*)?).map_err(Into::into)
},
Instantiate | Migrate | Reply | Sudo => {
emit_error!(name.span(), "Instantiation, Reply, Migrate and Sudo messages not supported on traits, they should be defined on contracts directly");
Instantiate | Migrate | Reply => {
emit_error!(name.span(), "Instantiation, Reply and Migrate messages not supported on traits, they should be defined on contracts directly");

Check warning on line 573 in sylvia-derive/src/message.rs

View check run for this annotation

Codecov / codecov/patch

sylvia-derive/src/message.rs#L572-L573

Added lines #L572 - L573 were not covered by tests
quote! {}
}
}
Expand Down
10 changes: 7 additions & 3 deletions sylvia-derive/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
Instantiate { name: Ident },
Migrate { name: Ident },
Reply,
Sudo,
}

impl MsgType {
Expand Down Expand Up @@ -171,7 +172,7 @@
}
}

pub fn emit_msg_name(&self, is_wrapper: bool) -> Type {
pub fn emit_msg_name(&self, is_wrapper: bool) -> Ident {
match self {
MsgType::Exec if is_wrapper => parse_quote! { ContractExecMsg },
MsgType::Query if is_wrapper => parse_quote! { ContractQueryMsg },
Expand All @@ -180,7 +181,7 @@
MsgType::Instantiate => parse_quote! { InstantiateMsg },
MsgType::Migrate => parse_quote! { MigrateMsg },
MsgType::Reply => parse_quote! { ReplyMsg },
MsgType::Sudo => todo!(),
MsgType::Sudo => parse_quote! { SudoMsg },
}
}

Expand Down Expand Up @@ -226,6 +227,7 @@
Instantiate { .. } => MsgType::Instantiate,
Migrate { .. } => MsgType::Migrate,
Reply => MsgType::Reply,
Sudo => MsgType::Sudo,
}
}
}
Expand All @@ -248,10 +250,12 @@
Ok(Self::Migrate { name })
} else if ty == "reply" {
Ok(Self::Reply)
} else if ty == "sudo" {
Ok(Self::Sudo)
} else {
Err(Error::new(
ty.span(),
"Invalid message type, expected one of: `exec`, `query`, `instantiate`, `migrate`",
"Invalid message type, expected one of: `exec`, `query`, `instantiate`, `migrate`, `reply` or `sudo`.",

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

View check run for this annotation

Codecov / codecov/patch

sylvia-derive/src/parser.rs#L258

Added line #L258 was not covered by tests
))
}
}
Expand Down
6 changes: 6 additions & 0 deletions sylvia/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@
}
}

impl<'a, C: CustomQuery> From<(DepsMut<'a, C>, Env)> for SudoCtx<'a, C> {
fn from((deps, env): (DepsMut<'a, C>, Env)) -> Self {

Check warning on line 100 in sylvia/src/types.rs

View check run for this annotation

Codecov / codecov/patch

sylvia/src/types.rs#L100

Added line #L100 was not covered by tests
Self { deps, env }
}
}

pub trait CustomMsg: cosmwasm_std::CustomMsg + DeserializeOwned {}

impl<T> CustomMsg for T where T: cosmwasm_std::CustomMsg + DeserializeOwned {}
Expand Down
21 changes: 18 additions & 3 deletions sylvia/tests/messages_generation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ mod interface {
use cosmwasm_std::{Addr, Decimal, Response, StdError};
use sylvia::{
interface,
types::{ExecCtx, QueryCtx},
types::{ExecCtx, QueryCtx, SudoCtx},
};

use crate::QueryResult;
Expand All @@ -42,6 +42,12 @@ mod interface {

#[msg(query)]
fn argumented_query(&self, ctx: QueryCtx, user: Addr) -> Result<QueryResult, Self::Error>;

#[msg(sudo)]
fn no_args_sudo(&self, ctx: SudoCtx) -> Result<Response, Self::Error>;

#[msg(sudo)]
fn argumented_sudo(&self, ctx: SudoCtx, user: Addr) -> Result<Response, Self::Error>;
}
}

Expand Down Expand Up @@ -113,13 +119,17 @@ mod contract {
#[test]
fn interface_messages_constructible() {
let no_args_exec = interface::sv::ExecMsg::NoArgsExecution {};
let _argumented_exec = interface::sv::ExecMsg::ArgumentedExecution {
let _ = interface::sv::ExecMsg::ArgumentedExecution {
addr: Addr::unchecked("owner"),
coef: Decimal::percent(10),
desc: "Some description".to_owned(),
};
let no_args_query = interface::sv::QueryMsg::NoArgsQuery {};
let _argumented_query = interface::sv::QueryMsg::ArgumentedQuery {
let _ = interface::sv::QueryMsg::ArgumentedQuery {
user: Addr::unchecked("owner"),
};
let no_args_sudo = interface::sv::SudoMsg::NoArgsSudo {};
let _ = interface::sv::SudoMsg::ArgumentedSudo {
user: Addr::unchecked("owner"),
};

Expand All @@ -133,6 +143,11 @@ fn interface_messages_constructible() {
interface::sv::QueryMsg::NoArgsQuery {} => (),
interface::sv::QueryMsg::ArgumentedQuery { .. } => (),
}

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

#[test]
Expand Down
Loading