sylvia_derive/contract/communication/
api.rs

1use crate::crate_module;
2use crate::parser::variant_descs::AsVariantDescs;
3use crate::parser::{Custom, MsgType};
4use crate::types::msg_variant::MsgVariants;
5use crate::utils::emit_bracketed_generics;
6use proc_macro2::TokenStream;
7use quote::quote;
8use syn::{GenericParam, ItemImpl};
9
10pub struct Api<'a> {
11    source: &'a ItemImpl,
12    exec_variants: MsgVariants<'a, GenericParam>,
13    query_variants: MsgVariants<'a, GenericParam>,
14    instantiate_variants: MsgVariants<'a, GenericParam>,
15    migrate_variants: MsgVariants<'a, GenericParam>,
16    sudo_variants: MsgVariants<'a, GenericParam>,
17    generics: &'a [&'a GenericParam],
18    custom: &'a Custom,
19}
20
21impl<'a> Api<'a> {
22    pub fn new(source: &'a ItemImpl, generics: &'a [&'a GenericParam], custom: &'a Custom) -> Self {
23        let exec_variants = MsgVariants::new(
24            source.as_variants(),
25            MsgType::Exec,
26            generics,
27            &source.generics.where_clause,
28        );
29
30        let query_variants = MsgVariants::new(
31            source.as_variants(),
32            MsgType::Query,
33            generics,
34            &source.generics.where_clause,
35        );
36
37        let instantiate_variants = MsgVariants::new(
38            source.as_variants(),
39            MsgType::Instantiate,
40            generics,
41            &source.generics.where_clause,
42        );
43
44        let migrate_variants = MsgVariants::new(
45            source.as_variants(),
46            MsgType::Migrate,
47            generics,
48            &source.generics.where_clause,
49        );
50
51        let sudo_variants = MsgVariants::new(
52            source.as_variants(),
53            MsgType::Sudo,
54            generics,
55            &source.generics.where_clause,
56        );
57
58        Self {
59            source,
60            exec_variants,
61            query_variants,
62            instantiate_variants,
63            migrate_variants,
64            sudo_variants,
65            generics,
66            custom,
67        }
68    }
69
70    pub fn emit(&self) -> TokenStream {
71        let sylvia = crate_module();
72        let Self {
73            source,
74            exec_variants,
75            query_variants,
76            instantiate_variants,
77            migrate_variants,
78            sudo_variants,
79            generics,
80            custom,
81        } = self;
82
83        let where_clause = &source.generics.where_clause;
84        let contract_name = &source.self_ty;
85        let exec_generics = &exec_variants.used_generics();
86        let query_generics = &query_variants.used_generics();
87        let instantiate_generics = &instantiate_variants.used_generics();
88        let migrate_generics = &migrate_variants.used_generics();
89        let sudo_generics = &sudo_variants.used_generics();
90
91        let bracket_generics = emit_bracketed_generics(generics);
92        let exec_bracketed_generics = emit_bracketed_generics(exec_generics);
93        let query_bracketed_generics = emit_bracketed_generics(query_generics);
94        let sudo_bracketed_generics = emit_bracketed_generics(sudo_generics);
95        let instantiate_bracketed_generics = emit_bracketed_generics(instantiate_generics);
96        let migrate_bracketed_generics = emit_bracketed_generics(migrate_generics);
97
98        let migrate_type = if migrate_variants.variants().count() != 0 {
99            quote! { type Migrate = MigrateMsg #migrate_bracketed_generics; }
100        } else {
101            quote! { type Migrate = #sylvia ::cw_std::Empty; }
102        };
103        let custom_msg = custom.msg_or_default();
104        let custom_query = custom.query_or_default();
105
106        quote! {
107            impl #bracket_generics #sylvia ::types::ContractApi for #contract_name #where_clause {
108                type ContractExec = ContractExecMsg #bracket_generics;
109                type ContractQuery = ContractQueryMsg #bracket_generics;
110                type ContractSudo = ContractSudoMsg #bracket_generics;
111                type Exec = ExecMsg #exec_bracketed_generics;
112                type Query = QueryMsg #query_bracketed_generics;
113                type Sudo = SudoMsg #sudo_bracketed_generics;
114                type Instantiate = InstantiateMsg #instantiate_bracketed_generics;
115                #migrate_type
116                type Remote<'remote> = #sylvia ::types::Remote<'remote, Self >;
117                type Querier<'querier> = #sylvia ::types::BoundQuerier<'querier, #custom_query, Self >;
118                type CustomMsg = #custom_msg;
119                type CustomQuery = #custom_query;
120            }
121        }
122    }
123}