sylvia_derive/parser/attributes/
attr.rs1use proc_macro2::{Span, TokenStream};
2use proc_macro_error::emit_error;
3use syn::parse::{Error, Parse, ParseStream, Parser};
4use syn::spanned::Spanned;
5use syn::{Ident, MetaList, Result, Token};
6
7use super::MsgType;
8
9#[derive(Clone, Debug)]
11pub struct VariantAttrForwarding {
12 pub attrs: TokenStream,
13 pub span: Span,
14}
15
16impl VariantAttrForwarding {
17 pub fn new(attr: &MetaList) -> Self {
18 VariantAttrForwarding {
19 attrs: attr.tokens.clone(),
20 span: attr.span(),
21 }
22 }
23}
24
25#[derive(Clone, Debug)]
27pub struct MsgAttrForwarding {
28 pub msg_type: MsgType,
29 pub attrs: TokenStream,
30}
31
32impl MsgAttrForwarding {
33 pub fn new(attr: &MetaList) -> Result<Self> {
34 MsgAttrForwarding::parse
35 .parse2(attr.tokens.clone())
36 .map_err(|err| {
37 emit_error!(attr.tokens.span(), err);
38 err
39 })
40 }
41}
42
43impl Parse for MsgAttrForwarding {
44 fn parse(input: ParseStream) -> Result<Self> {
45 let error_msg =
46 "Expected attribute of the form: `#[sv::msg_attr(msg_type, attribute_to_forward)]`";
47 let msg_type: Ident = input
48 .parse()
49 .map_err(|err| Error::new(err.span(), error_msg))?;
50 let _: Token![,] = input
51 .parse()
52 .map_err(|err| Error::new(err.span(), error_msg))?;
53 let attrs: TokenStream = input
54 .parse()
55 .map_err(|err| Error::new(err.span(), error_msg))?;
56 if attrs.is_empty() {
57 return Err(Error::new(attrs.span(), error_msg));
58 }
59 let msg_type = match msg_type.to_string().as_str() {
60 "exec" => MsgType::Exec,
61 "query" => MsgType::Query,
62 "instantiate" => MsgType::Instantiate,
63 "migrate" => MsgType::Migrate,
64 "reply" => MsgType::Reply,
65 "sudo" => MsgType::Sudo,
66 _ => return Err(Error::new(
67 msg_type.span(),
68 "Invalid message type, expected one of: `exec`, `query`, `instantiate`, `migrate`, `reply` or `sudo`.",
69 ))
70 };
71 Ok(Self { msg_type, attrs })
72 }
73}