ink_codegen/generator/trait_def/
mod.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
15mod call_builder;
16mod call_forwarder;
17mod definition;
18mod message_builder;
19mod trait_registry;
20
21use derive_more::From;
22use ink_primitives::abi::Abi;
23use proc_macro2::{
24    Span,
25    TokenStream as TokenStream2,
26};
27use quote::{
28    format_ident,
29    quote_spanned,
30};
31
32use crate::GenerateCode;
33
34/// Generator to create the ink! storage struct and important trait implementations.
35#[derive(From, Copy, Clone)]
36pub struct TraitDefinition<'a> {
37    trait_def: &'a ir::InkTraitDefinition,
38    abi: Option<Abi>,
39}
40
41impl<'a> From<&'a ir::InkTraitDefinition> for TraitDefinition<'a> {
42    #[inline]
43    fn from(value: &'a ir::InkTraitDefinition) -> Self {
44        TraitDefinition {
45            trait_def: value,
46            abi: None,
47        }
48    }
49}
50
51impl TraitDefinition<'_> {
52    /// Appends the trait suffix to the string and forms an identifier.
53    ///
54    /// This appends the `_$NAME_$TRAIT_ID` string to the prefix string
55    /// were `$NAME` is the non-unique name of the trait and `$TRAIT_ID`
56    /// is the hex representation of the unique 4-byte trait identifier.
57    fn append_trait_suffix(&self, prefix: &str) -> syn::Ident {
58        format_ident!("__ink_{}{}", prefix, self.trait_def.item().ident(),)
59    }
60
61    /// Returns the span of the underlying ink! trait definition.
62    fn span(&self) -> Span {
63        self.trait_def.item().span()
64    }
65}
66
67impl GenerateCode for TraitDefinition<'_> {
68    fn generate_code(&self) -> TokenStream2 {
69        let span = self.trait_def.item().span();
70        let trait_definition = self.generate_trait_definition();
71        let trait_registry = self.generate_trait_registry_impl(self.abi);
72        let trait_message_builder = self.generate_message_builder(self.abi);
73        let trait_call_builder = self.generate_call_builder(self.abi);
74        let trait_call_forwarder = self.generate_call_forwarder(self.abi);
75        quote_spanned!(span =>
76            #trait_definition
77            const _: () = {
78                #trait_registry
79                #trait_message_builder
80                #trait_call_builder
81                #trait_call_forwarder
82            };
83        )
84    }
85}