sylvia_derive/interface/communication/
api.rs1use crate::crate_module;
2use crate::parser::variant_descs::AsVariantDescs;
3use crate::parser::{Custom, MsgType};
4use crate::types::associated_types::{AssociatedTypes, ItemType};
5use crate::types::msg_variant::MsgVariants;
6use proc_macro2::TokenStream;
7use quote::quote;
8use syn::ItemTrait;
9
10pub struct Api<'a> {
16 source: &'a ItemTrait,
17 custom: &'a Custom,
18 associated_types: &'a AssociatedTypes<'a>,
19}
20
21impl<'a> Api<'a> {
22 pub fn new(
23 source: &'a ItemTrait,
24 custom: &'a Custom,
25 associated_types: &'a AssociatedTypes<'a>,
26 ) -> Self {
27 Self {
28 source,
29 custom,
30 associated_types,
31 }
32 }
33
34 pub fn emit(&self) -> TokenStream {
35 let sylvia = crate_module();
36 let Self {
37 source,
38 custom,
39 associated_types,
40 } = self;
41
42 let where_clause = &self.associated_types.as_where_clause();
43 let custom_query = custom.query_or_default();
44 let interface_name = &source.ident;
45 let generics: Vec<_> = associated_types
46 .without_error()
47 .map(ItemType::as_name)
48 .collect();
49 let exec_variants = MsgVariants::new(
50 source.as_variants(),
51 MsgType::Exec,
52 &generics,
53 &source.generics.where_clause,
54 );
55 let query_variants = MsgVariants::new(
56 source.as_variants(),
57 MsgType::Query,
58 &generics,
59 &source.generics.where_clause,
60 );
61 let sudo_variants = MsgVariants::new(
62 source.as_variants(),
63 MsgType::Sudo,
64 &generics,
65 &source.generics.where_clause,
66 );
67
68 let exec_generics = &exec_variants.used_generics();
69 let query_generics = &query_variants.used_generics();
70 let sudo_generics = &sudo_variants.used_generics();
71
72 let phantom = if !generics.is_empty() {
73 quote! {
74 _phantom: std::marker::PhantomData<( #(#generics,)* )>,
75 }
76 } else {
77 quote! {}
78 };
79
80 quote! {
81 pub trait InterfaceMessagesApi {
82 type Exec;
83 type Query;
84 type Sudo;
85 type Querier<'querier>;
86 }
87
88 impl<Contract: #interface_name> InterfaceMessagesApi for Contract {
89 type Exec = ExecMsg < #(<Contract as #interface_name >:: #exec_generics,)* >;
90 type Query = QueryMsg < #(<Contract as #interface_name >:: #query_generics,)* >;
91 type Sudo = SudoMsg < #(<Contract as #interface_name >:: #sudo_generics ,)* >;
92 type Querier<'querier> = #sylvia ::types::BoundQuerier<'querier, #custom_query, Contract >;
93 }
94
95 impl<'sv_iface_msg_api, Error, #(#generics),*> InterfaceMessagesApi for dyn #interface_name < Error = Error, #(#generics = #generics,)* > + 'sv_iface_msg_api {
96 type Exec = ExecMsg < #(#exec_generics,)* >;
97 type Query = QueryMsg < #(#query_generics,)* >;
98 type Sudo = SudoMsg < #(#sudo_generics,)* >;
99 type Querier<'querier> = #sylvia ::types::BoundQuerier<'querier, #custom_query, Self >;
100 }
101
102 pub struct Api < #(#generics,)* > {
103 #phantom
104 }
105
106 #[allow(deprecated)]
107 impl < #(#generics,)* > #sylvia ::types::InterfaceApi for Api < #(#generics,)* > #where_clause {
108 type Exec = ExecMsg < #(#exec_generics,)* >;
109 type Query = QueryMsg < #(#query_generics,)* >;
110 type Sudo = SudoMsg < #(#sudo_generics,)* >;
111 type Querier<'querier, Contract> = #sylvia ::types::BoundQuerier<'querier, #custom_query, Contract >;
112 }
113 }
114 }
115}