ink_codegen/generator/
storage.rs1use crate::GenerateCode;
16use derive_more::From;
17use proc_macro2::TokenStream as TokenStream2;
18use quote::{
19 quote,
20 quote_spanned,
21};
22use syn::spanned::Spanned as _;
23
24#[derive(From)]
26pub struct Storage<'a> {
27 contract: &'a ir::Contract,
28}
29impl_as_ref_for_generator!(Storage);
30
31impl GenerateCode for Storage<'_> {
32 fn generate_code(&self) -> TokenStream2 {
33 let storage_span = self.contract.module().storage().span();
34 let access_env_impls = self.generate_access_env_trait_impls();
35 let storage_struct = self.generate_storage_struct();
36 quote_spanned!(storage_span =>
37 #storage_struct
38 #access_env_impls
39
40 const _: () = {
41 #[allow(unused_imports)]
43 use ::ink::codegen::{
44 Env as _,
45 StaticEnv as _,
46 };
47 };
48 )
49 }
50}
51
52impl Storage<'_> {
53 fn generate_access_env_trait_impls(&self) -> TokenStream2 {
54 let storage_ident = &self.contract.module().storage().ident();
55 quote! {
56 const _: () = {
57 impl<'a> ::ink::codegen::Env for &'a #storage_ident {
58 type EnvAccess = ::ink::EnvAccess<
59 'a, <#storage_ident as ::ink::env::ContractEnv>::Env>;
60
61 fn env(self) -> Self::EnvAccess {
62 <<Self as ::ink::codegen::Env>::EnvAccess
63 as ::core::default::Default>::default()
64 }
65 }
66
67 impl<'a> ::ink::codegen::StaticEnv for #storage_ident {
68 type EnvAccess = ::ink::EnvAccess<
69 'static, <#storage_ident as ::ink::env::ContractEnv>::Env>;
70
71 fn env() -> Self::EnvAccess {
72 <<Self as ::ink::codegen::StaticEnv>::EnvAccess
73 as ::core::default::Default>::default()
74 }
75 }
76 };
77 }
78 }
79
80 fn generate_storage_struct(&self) -> TokenStream2 {
92 let storage = self.contract.module().storage();
93 let span = storage.span();
94 let ident = storage.ident();
95 let generics = storage.generics();
96 let attrs = storage.attrs();
97 let fields = storage.fields();
98 quote_spanned!( span =>
99 #(#attrs)*
100 #[::ink::storage_item]
101 #[cfg_attr(test, derive(::core::fmt::Debug))]
102 #[cfg(not(target_vendor = "fortanix"))]
103 pub struct #ident #generics {
104 #( #fields ),*
105 }
106
107 const _: () = {
108 impl ::ink::reflect::ContractName for #ident {
109 const NAME: &'static str = ::core::stringify!(#ident);
110 }
111 };
112 )
113 }
114}