sylvia_derive/parser/attributes/
custom.rs1use proc_macro_error::emit_error;
2use syn::parse::{Parse, ParseStream, Parser};
3use syn::{parse_quote, Error, Ident, MetaList, Result, Token, Type};
4
5use crate::crate_module;
6
7#[derive(Debug, Default)]
9pub struct Custom {
10 pub msg: Option<Type>,
11 pub query: Option<Type>,
12}
13
14impl Custom {
15 pub fn new(attr: &MetaList) -> Result<Self> {
16 Custom::parse.parse2(attr.tokens.clone()).map_err(|err| {
17 emit_error!(err.span(), err);
18 err
19 })
20 }
21
22 pub fn msg_or_default(&self) -> Type {
23 self.msg.clone().unwrap_or_else(Self::default_type)
24 }
25
26 pub fn query_or_default(&self) -> Type {
27 self.query.clone().unwrap_or_else(Self::default_type)
28 }
29
30 pub fn default_type() -> Type {
31 let sylvia = crate_module();
32 parse_quote! { #sylvia ::cw_std::Empty }
33 }
34}
35
36impl Parse for Custom {
37 fn parse(input: ParseStream) -> Result<Self> {
38 let mut custom = Self::default();
39
40 while !input.is_empty() {
41 let ty: Ident = input.parse()?;
42 let _: Token![=] = input.parse()?;
43 match ty.to_string().as_str() {
44 "msg" => custom.msg = Some(input.parse()?),
45 "query" => custom.query = Some(input.parse()?),
46 _ => {
47 return Err(Error::new(
48 ty.span(),
49 "Invalid custom type.\n
50 = note: Expected `#[sv::custom(msg=SomeMsg, query=SomeQuery)]`.\n",
51 ))
52 }
53 }
54 if !input.peek(Token![,]) {
55 break;
56 }
57 let _: Token![,] = input.parse()?;
58 }
59
60 Ok(custom)
61 }
62}