Skip to content

Commit

Permalink
feat: Make as Variant optional for #[messages(...)] attribtue
Browse files Browse the repository at this point in the history
  • Loading branch information
kulikthebird authored Jan 31, 2024
1 parent 711508b commit 7fe53ea
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 29 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,11 @@ pub struct MyContract<'a> {

#[contract]
#[messages(group as Group)]
// Alternatively:
// It's not needed to provide the interface's
// name if it's corresponds to the last segment
// of the module path:
// #[messages(group)]
impl group::Group for MyContract<'_> {
type Error = ContractError;

Expand Down Expand Up @@ -385,7 +390,10 @@ matching the trait name, but written "snake_case" instead of CamelCase. Here I h
`group` module for the `Group` trait, but the `CrossStaking` trait should be placed
in its own `cross_staking` module (note the underscore). This is a requirement right
now - Sylvia generates all the messages and boilerplate in this module and will try
to access them through this module.
to access them through this module. If the interface's name is a camel-case
version of the last module path's segment, the `as InterfaceName` can be omitted.
F.e. `#[messages(cw1 as Cw1)]` can be reduced to `#[messages(cw1)]`


Then there is the `Error` type embedded in the trait - it is also needed there,
and the trait bound here has to be at least `From<StdError>`, as Sylvia might
Expand Down
30 changes: 23 additions & 7 deletions sylvia-derive/src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use convert_case::{Case, Casing};
use proc_macro2::{Punct, TokenStream};
use proc_macro_error::emit_error;
use proc_macro_error::{emit_error, emit_warning};
use quote::quote;
use syn::fold::Fold;
use syn::parse::{Error, Nothing, Parse, ParseBuffer, ParseStream, Parser};
Expand Down Expand Up @@ -349,18 +350,33 @@ impl Parse for ContractMessageAttr {
let generics = extract_generics_from_path(&module);
let module = StripGenerics.fold_path(module);

let _: Token![as] = input.parse()?;
let variant = input.parse()?;

let variant = if input.parse::<Token![as]>().is_ok() {
let variant: Ident = input.parse()?;
if Some(variant.to_string())
== module
.segments
.last()
.map(|name| name.ident.to_string().to_case(Case::UpperCamel))
{
emit_warning!(
variant.span(), "Redundant `as {}`.", variant;
note = "Interface name is a camel case version of the path and can be auto deduced."
)
}
variant
} else if let Some(module_name) = &module.segments.last() {
let interface_name = module_name.ident.to_string().to_case(Case::UpperCamel);
syn::Ident::new(&interface_name, module.span())
} else {
Ident::new("", module.span())
};
let customs = interface_has_custom(input)?;

if !input.is_empty() {
return Err(Error::new(
input.span(),
"Unexpected token on the end of `message` attribtue",
"Unexpected token on the end of `messages` attribtue",
));
}

Ok(Self {
module,
variant,
Expand Down
16 changes: 8 additions & 8 deletions sylvia/tests/custom_msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ mod impl_some_interface {
use crate::{MyMsg, SomeResponse};

#[contract(module=crate)]
#[messages(crate::some_interface as SomeInterface)]
#[messages(crate::some_interface)]
#[sv::custom(msg=MyMsg)]
impl SomeInterface for crate::MyContract {
type Error = StdError;
Expand Down Expand Up @@ -93,7 +93,7 @@ mod impl_interface {
use sylvia::types::ExecCtx;

#[contract(module=crate)]
#[messages(crate::interface as Interface)]
#[messages(crate::interface)]
#[sv::custom(msg=MyMsg)]
impl Interface for crate::MyContract {
type Error = StdError;
Expand Down Expand Up @@ -127,7 +127,7 @@ mod impl_other_interface {
use sylvia::types::ExecCtx;

#[contract(module=crate)]
#[messages(crate::other_interface as OtherInterface)]
#[messages(crate::other_interface)]
#[sv::custom(msg=crate::MyMsg)]
impl OtherInterface for crate::MyContract {
type Error = StdError;
Expand Down Expand Up @@ -162,7 +162,7 @@ mod impl_associated_interface {
use sylvia::types::ExecCtx;

#[contract(module=crate)]
#[messages(crate::associated_interface as AssociatedInterface)]
#[messages(crate::associated_interface)]
#[sv::custom(msg=MyMsg)]
impl AssociatedInterface for crate::MyContract {
type Error = StdError;
Expand All @@ -176,10 +176,10 @@ mod impl_associated_interface {
}

#[contract]
#[messages(some_interface as SomeInterface)]
#[messages(other_interface as OtherInterface: custom(msg))]
#[messages(associated_interface as AssociatedInterface)]
#[messages(interface as Interface)]
#[messages(some_interface)]
#[messages(other_interface: custom(msg))]
#[messages(associated_interface)]
#[messages(interface)]
#[sv::custom(msg=MyMsg)]
impl MyContract {
#[allow(clippy::new_without_default)]
Expand Down
16 changes: 8 additions & 8 deletions sylvia/tests/custom_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ mod impl_interface {
use crate::{MyQuery, OtherQuery, SomeResponse};

#[contract(module=crate)]
#[messages(crate::interface as Interface)]
#[messages(crate::interface)]
#[sv::custom(query=MyQuery)]
impl crate::interface::Interface for crate::MyContract {
type Error = StdError;
Expand Down Expand Up @@ -97,7 +97,7 @@ mod impl_some_interface {
use crate::{MyQuery, SomeResponse};

#[contract(module=crate)]
#[messages(crate::some_interface as SomeInterface)]
#[messages(crate::some_interface)]
#[sv::custom(query=MyQuery)]
impl super::some_interface::SomeInterface for crate::MyContract {
type Error = StdError;
Expand Down Expand Up @@ -143,7 +143,7 @@ mod impl_associated_type_interface {
use sylvia_derive::contract;

#[contract(module=crate)]
#[messages(crate::associated_type_interface as AssociatedTypeInterface)]
#[messages(crate::associated_type_interface)]
impl AssociatedTypeInterface for crate::MyContract {
type Error = StdError;
type QueryC = MyQuery;
Expand Down Expand Up @@ -188,7 +188,7 @@ mod impl_default_query_interface {
use sylvia_derive::contract;

#[contract(module=crate)]
#[messages(crate::default_query_interface as DefaultQueryInterface)]
#[messages(crate::default_query_interface)]
#[sv::custom(query=MyQuery)]
impl DefaultQueryInterface for crate::MyContract {
type Error = StdError;
Expand All @@ -206,10 +206,10 @@ mod impl_default_query_interface {
}

#[contract]
#[messages(some_interface as SomeInterface)]
#[messages(associated_type_interface as AssociatedTypeInterface)]
#[messages(interface as Interface)]
#[messages(default_query_interface as DefaultQueryInterface: custom(query))]
#[messages(some_interface)]
#[messages(associated_type_interface)]
#[messages(interface)]
#[messages(default_query_interface: custom(query))]
#[sv::custom(query=MyQuery)]
impl MyContract {
#[allow(clippy::new_without_default)]
Expand Down
4 changes: 2 additions & 2 deletions sylvia/tests/dispatching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ mod impl_interface {
use crate::{EmptyQueryResponse, QueryResponse};

#[sylvia::contract(module = crate::contract)]
#[messages(crate::interface as Interface)]
#[messages(crate::interface)]
impl crate::interface::Interface for crate::contract::Contract {
type Error = StdError;

Expand Down Expand Up @@ -115,7 +115,7 @@ mod contract {
#[allow(dead_code)]
#[cfg(not(tarpaulin_include))]
#[contract]
#[messages(crate::interface as Interface)]
#[messages(crate::interface)]
impl Contract {
fn new() -> Self {
Self::default()
Expand Down
4 changes: 2 additions & 2 deletions sylvia/tests/querier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub mod impl_counter {
use sylvia::types::{ExecCtx, QueryCtx};

#[contract(module=crate)]
#[messages(crate::counter as Counter)]
#[messages(crate::counter)]
impl Counter for super::CounterContract<'_> {
type Error = StdError;

Expand Down Expand Up @@ -98,7 +98,7 @@ pub struct CounterContract<'a> {
}

#[contract]
#[messages(counter as Counter)]
#[messages(counter)]
impl CounterContract<'_> {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Expand Down
2 changes: 1 addition & 1 deletion sylvia/tests/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub mod some_interface {
}

#[contract]
#[messages(some_interface as SomeInterface)]
#[messages(some_interface)]
impl SomeContract {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Expand Down

0 comments on commit 7fe53ea

Please sign in to comment.