ink_codegen/generator/trait_def/
definition.rs

1// Copyright (C) Use Ink (UK) Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Generates the ink! trait definition item.
16
17use super::TraitDefinition;
18use heck::ToLowerCamelCase as _;
19use proc_macro2::TokenStream as TokenStream2;
20use quote::{
21    format_ident,
22    quote,
23    quote_spanned,
24};
25
26impl TraitDefinition<'_> {
27    fn generate_for_message(message: ir::InkTraitMessage<'_>) -> TokenStream2 {
28        let span = message.span();
29        let attrs = message.attrs();
30        let sig = message.sig();
31        let ident = &sig.ident;
32        let inputs = &sig.inputs;
33        let cfg_attrs = message.get_cfg_attrs(span);
34        let output = match &sig.output {
35            syn::ReturnType::Default => quote! { () },
36            syn::ReturnType::Type(_, ty) => quote! { #ty },
37        };
38        let output_ident =
39            format_ident!("{}Output", ident.to_string().to_lower_camel_case());
40        quote_spanned!(span =>
41            /// Output type of the respective trait message.
42            #(#cfg_attrs)*
43            type #output_ident: ::ink::codegen::ImpliesReturn<#output>;
44
45            #(#attrs)*
46            fn #ident(#inputs) -> Self::#output_ident;
47        )
48    }
49}
50
51impl TraitDefinition<'_> {
52    pub(super) fn generate_trait_definition(&self) -> TokenStream2 {
53        let item = self.trait_def.item();
54        let span = item.span();
55        let attrs = item.attrs();
56        let ident = item.ident();
57        let messages = item
58            .iter_items()
59            .map(|(item, _)| item)
60            .flat_map(ir::InkTraitItem::filter_map_message)
61            .map(Self::generate_for_message);
62        quote_spanned!(span =>
63            #(#attrs)*
64            pub trait #ident: ::ink::env::ContractEnv {
65                /// Holds general and global information about the trait.
66                #[doc(hidden)]
67                #[allow(non_camel_case_types)]
68                type __ink_TraitInfo: ::ink::codegen::TraitCallForwarder;
69
70                #(#messages)*
71            }
72        )
73    }
74}