diff --git a/sylvia-derive/src/parser/attributes/mod.rs b/sylvia-derive/src/parser/attributes/mod.rs index d0d00ff9..c3b3cb5f 100644 --- a/sylvia-derive/src/parser/attributes/mod.rs +++ b/sylvia-derive/src/parser/attributes/mod.rs @@ -81,12 +81,13 @@ impl ParsedSylviaAttributes { } if let Some(attr) = result.variant_attrs_forward.first() { - if let Some(MsgAttr::Instantiate) = result.msg_attr { + let msg_type = result.msg_attr.as_ref().map(MsgAttr::msg_type); + if let Some(MsgType::Instantiate) = msg_type { emit_error!( attr.span, "The attribute `sv::attr` is not supported for `instantiate`"; note = "Message `instantiate` is a structure, use `#[sv::msg_attr] instead`"; ); - } else if let Some(MsgAttr::Migrate) = result.msg_attr { + } else if let Some(MsgType::Migrate) = msg_type { emit_error!( attr.span, "The attribute `sv::attr` is not supported for `migrate`"; note = "Message `migrate` is a structure, use `#[sv::msg_attr] instead`"; diff --git a/sylvia-derive/src/parser/attributes/msg.rs b/sylvia-derive/src/parser/attributes/msg.rs index c415f53a..446dd334 100644 --- a/sylvia-derive/src/parser/attributes/msg.rs +++ b/sylvia-derive/src/parser/attributes/msg.rs @@ -2,7 +2,8 @@ use proc_macro_error::emit_error; use syn::parse::{Error, Parse, ParseStream, Parser}; use syn::{bracketed, Ident, MetaList, Result, Token}; -/// Type of message to be generated +/// Supported message types. +/// Representation of the first parameter in `#[sv::msg(..)] attribute. #[derive(PartialEq, Eq, Debug, Clone, Copy)] pub enum MsgType { Exec, @@ -16,7 +17,7 @@ pub enum MsgType { /// ArgumentParser holds `resp` parameter parsed from `sv::msg` attribute. #[derive(Default)] struct ArgumentParser { - pub resp_type: Option, + pub query_resp_type: Option, pub reply_handlers: Vec, pub reply_on: Option, } @@ -32,7 +33,7 @@ impl Parse for ArgumentParser { "resp" => { let _: Token![=] = input.parse()?; let resp_type: Ident = input.parse()?; - result.resp_type = Some(resp_type); + result.query_resp_type = Some(resp_type); } "handlers" => { let _: Token![=] = input.parse()?; @@ -91,18 +92,11 @@ impl ReplyOn { /// Parsed representation of `#[sv::msg(...)]` attribute. #[derive(Clone)] -pub enum MsgAttr { - Exec, - Query { - resp_type: Option, - }, - Instantiate, - Migrate, - Reply { - _handlers: Vec, - _reply_on: ReplyOn, - }, - Sudo, +pub struct MsgAttr { + msg_type: MsgType, + query_resp_type: Option, + _reply_handlers: Vec, + _reply_on: ReplyOn, } impl MsgAttr { @@ -112,6 +106,14 @@ impl MsgAttr { err }) } + + pub fn msg_type(&self) -> MsgType { + self.msg_type + } + + pub fn resp_type(&self) -> &Option { + &self.query_resp_type + } } impl PartialEq for MsgAttr { @@ -120,40 +122,21 @@ impl PartialEq for MsgAttr { } } -impl MsgAttr { - pub fn msg_type(&self) -> MsgType { - match self { - Self::Exec { .. } => MsgType::Exec, - Self::Query { .. } => MsgType::Query, - Self::Instantiate { .. } => MsgType::Instantiate, - Self::Migrate { .. } => MsgType::Migrate, - Self::Reply { .. } => MsgType::Reply, - Self::Sudo { .. } => MsgType::Sudo, - } - } -} - impl Parse for MsgAttr { fn parse(input: ParseStream) -> Result { - let ty: Ident = input.parse()?; + let msg_type: Ident = input.parse()?; + let msg_type = MsgType::new(&msg_type)?; let ArgumentParser { - resp_type, + query_resp_type, reply_handlers, reply_on, } = ArgumentParser::parse(input)?; - let result = match ty.to_string().as_str() { - "exec" => Self::Exec, - "query" => Self::Query { resp_type }, - "instantiate" => Self::Instantiate, - "migrate" => Self::Migrate, - "reply" => Self::Reply {_handlers: reply_handlers, _reply_on: reply_on.unwrap_or_default()}, - "sudo" => Self::Sudo, - _ => return Err(Error::new( - input.span(), - "Invalid message type, expected one of: `exec`, `query`, `instantiate`, `migrate`, `reply` or `sudo`.", - )) - }; - Ok(result) + Ok(Self { + msg_type, + query_resp_type, + _reply_handlers: reply_handlers, + _reply_on: reply_on.unwrap_or_default(), + }) } } diff --git a/sylvia-derive/src/types/msg_type.rs b/sylvia-derive/src/types/msg_type.rs index b89edf05..182ad197 100644 --- a/sylvia-derive/src/types/msg_type.rs +++ b/sylvia-derive/src/types/msg_type.rs @@ -2,7 +2,8 @@ use proc_macro2::TokenStream; use proc_macro_error::emit_error; use quote::quote; use syn::fold::Fold; -use syn::{parse_quote, GenericParam, Ident, Type}; +use syn::parse::Error; +use syn::{parse_quote, GenericParam, Ident, Result, Type}; use crate::crate_module; use crate::fold::StripSelfPath; @@ -10,6 +11,21 @@ use crate::parser::attributes::msg::MsgType; use crate::parser::Customs; impl MsgType { + pub fn new(msg_type: &Ident) -> Result { + match msg_type.to_string().as_str() { + "exec" => Ok(Self::Exec), + "query" => Ok(Self::Query ), + "instantiate" => Ok(Self::Instantiate), + "migrate" => Ok(Self::Migrate), + "reply" => Ok(Self::Reply ), + "sudo" => Ok(Self::Sudo), + _ => return Err(Error::new( + msg_type.span(), + "Invalid message type, expected one of: `exec`, `query`, `instantiate`, `migrate`, `reply` or `sudo`.", + )) + } + } + pub fn emit_ctx_type(self, query_type: &Type) -> TokenStream { use MsgType::*; diff --git a/sylvia-derive/src/types/msg_variant.rs b/sylvia-derive/src/types/msg_variant.rs index 75f06f4c..55b426c5 100644 --- a/sylvia-derive/src/types/msg_variant.rs +++ b/sylvia-derive/src/types/msg_variant.rs @@ -44,7 +44,8 @@ impl<'a> MsgVariant<'a> { let fields = process_fields(sig, generics_checker); let msg_type = msg_attr.msg_type(); - let return_type = if let MsgAttr::Query { resp_type, .. } = msg_attr { + let return_type = if msg_attr.msg_type() == MsgType::Query { + let resp_type = &msg_attr.resp_type(); match resp_type { Some(resp_type) => { let resp_type = parse_quote! { #resp_type };