sylvia_derive/parser/attributes/
override_entry_point.rs1use proc_macro2::TokenStream;
2use proc_macro_error::emit_error;
3use quote::quote;
4use syn::parse::{Error, Parse, ParseStream, Parser};
5use syn::{parenthesized, Ident, MetaList, Path, Result, Token, Type};
6
7use crate::crate_module;
8use crate::parser::MsgType;
9
10#[derive(Debug, Clone)]
12pub struct OverrideEntryPoint {
13 entry_point: Path,
14 msg_name: Type,
15 msg_type: MsgType,
16}
17
18impl OverrideEntryPoint {
19 pub fn new(attr: &MetaList) -> Result<Self> {
20 OverrideEntryPoint::parse
21 .parse2(attr.tokens.clone())
22 .map_err(|err| {
23 emit_error!(err.span(), err);
24 err
25 })
26 }
27
28 pub fn emit_multitest_dispatch(&self) -> TokenStream {
29 let Self {
30 entry_point,
31 msg_name,
32 msg_type,
33 ..
34 } = self;
35
36 let sylvia = crate_module();
37 let values = msg_type.emit_ctx_values();
38
39 quote! {
40 #entry_point ( #values .into(), #sylvia ::cw_std::from_json::< #msg_name >(&msg)?)
41 .map_err(Into::into)
42 }
43 }
44}
45
46pub trait FilteredOverrideEntryPoints {
47 fn get_entry_point(&self, ty: MsgType) -> Option<&OverrideEntryPoint>;
48}
49
50impl FilteredOverrideEntryPoints for &[OverrideEntryPoint] {
51 fn get_entry_point(&self, ty: MsgType) -> Option<&OverrideEntryPoint> {
52 self.iter().find(|entry_point| entry_point.msg_type == ty)
53 }
54}
55
56impl FilteredOverrideEntryPoints for &Vec<OverrideEntryPoint> {
57 fn get_entry_point(&self, ty: MsgType) -> Option<&OverrideEntryPoint> {
58 self.iter().find(|entry_point| entry_point.msg_type == ty)
59 }
60}
61
62impl Parse for OverrideEntryPoint {
63 fn parse(input: ParseStream) -> Result<Self> {
64 let ty: Ident = input.parse()?;
65 let _: Token![=] = input.parse()?;
66 let entry_point = input.parse()?;
67
68 let msg_content;
69 parenthesized!(msg_content in input);
70
71 let msg_name = msg_content.parse()?;
72
73 let msg_type = match ty.to_string().as_str() {
74 "exec" => MsgType::Exec,
75 "instantiate" => MsgType::Instantiate,
76 "query" => MsgType::Instantiate,
77 "migrate" => MsgType::Migrate,
78 "reply" => MsgType::Reply,
79 "sudo" => MsgType::Sudo,
80 &_ => {
81 return Err(Error::new(
82 ty.span(),
83 "Invalid entry point. Expected exec, instantiate, query, migrate, reply or sudo. Found {ty}",
84 ))
85 }
86 };
87
88 Ok(Self {
89 entry_point,
90 msg_name,
91 msg_type,
92 })
93 }
94}