@@ -17,24 +17,6 @@ pub fn contract_state(_attr: TokenStream, item: TokenStream) -> TokenStream {
1717 f. attrs . iter ( ) . any ( |attr| attr. path ( ) . is_ident ( "flat" ) )
1818 } ;
1919
20- let is_map = |f : & syn:: Field | -> bool {
21- if let Type :: Path ( type_path) = & f. ty {
22- if let Some ( segment) = type_path. path . segments . first ( ) {
23- return segment. ident == "Map" ;
24- }
25- }
26- false
27- } ;
28-
29- let is_map_nested = |f : & syn:: Field | -> bool {
30- if let Type :: Path ( type_path) = & f. ty {
31- if let Some ( segment) = type_path. path . segments . first ( ) {
32- return segment. ident == "MapNested" ;
33- }
34- }
35- false
36- } ;
37-
3820 let transformed_fields = fields. named . iter ( ) . map ( |f| {
3921 let field_name = & f. ident ;
4022 let field_vis = & f. vis ;
@@ -56,45 +38,34 @@ pub fn contract_state(_attr: TokenStream, item: TokenStream) -> TokenStream {
5638 }
5739 } ) ;
5840
59- let init_calls = fields. named . iter ( ) . map ( |f| {
41+ let init_fields = fields. named . iter ( ) . map ( |f| {
6042 let field = f. ident . as_ref ( ) . unwrap ( ) ;
43+ let field_ty = & f. ty ;
6144 let key = field. to_string ( ) ;
6245
6346 if is_flat ( f) {
6447 quote ! {
65- let mut key = prefix. clone( ) ;
66- key. extend_from_slice( #key. as_bytes( ) ) ;
67- self . #field = LazyCell :: new( key) ;
68- }
69- } else if is_map ( f) || is_map_nested ( f) {
70- quote ! {
71- let mut key = prefix. clone( ) ;
72- key. extend_from_slice( #key. as_bytes( ) ) ;
73- self . #field. __init_lazy_fields( key) ;
48+ #field: {
49+ let mut key = prefix. clone( ) ;
50+ key. extend_from_slice( #key. as_bytes( ) ) ;
51+ LazyCell :: with_prefix( key)
52+ }
7453 }
7554 } else {
7655 quote ! {
77- let mut key = prefix. clone( ) ;
78- key. extend_from_slice( #key. as_bytes( ) ) ;
79- key. push( b':' ) ;
80- self . #field. __init_lazy_fields( key) ;
56+ #field: {
57+ let mut key = prefix. clone( ) ;
58+ key. extend_from_slice( #key. as_bytes( ) ) ;
59+ key. push( b':' ) ;
60+ #field_ty:: with_prefix( key)
61+ }
8162 }
8263 }
8364 } ) ;
8465
8566 let flush_calls = fields. named . iter ( ) . map ( |f| {
8667 let field = f. ident . as_ref ( ) . unwrap ( ) ;
87-
88- if is_flat ( f) {
89- quote ! { self . #field. flush( ) ; }
90- } else {
91- quote ! { self . #field. __flush_lazy_fields( ) ; }
92- }
93- } ) ;
94-
95- let default_fields = fields. named . iter ( ) . map ( |f| {
96- let field_name = & f. ident ;
97- quote ! { #field_name: Default :: default ( ) }
68+ quote ! { self . #field. flush( ) ; }
9869 } ) ;
9970
10071 TokenStream :: from ( quote ! {
@@ -103,18 +74,14 @@ pub fn contract_state(_attr: TokenStream, item: TokenStream) -> TokenStream {
10374 #( #transformed_fields) , *
10475 }
10576
106- impl Default for #name {
107- fn default ( ) -> Self {
108- Self { #( #default_fields) , * }
109- }
110- }
111-
11277 impl ContractState for #name {
113- fn __init_lazy_fields( & mut self , prefix: alloc:: vec:: Vec <u8 >) {
114- #( #init_calls) *
78+ fn with_prefix( prefix: alloc:: vec:: Vec <u8 >) -> Self {
79+ Self {
80+ #( #init_fields) , *
81+ }
11582 }
11683
117- fn __flush_lazy_fields ( & self ) {
84+ fn flush ( & self ) {
11885 #( #flush_calls) *
11986 }
12087 }
@@ -132,6 +99,21 @@ pub fn contract(_attr: TokenStream, item: TokenStream) -> TokenStream {
13299 item
133100}
134101
102+ fn is_integer_type ( ty : & Type ) -> bool {
103+ if let Type :: Path ( type_path) = ty {
104+ if let Some ( segment) = type_path. path . segments . first ( ) {
105+ let ident = & segment. ident ;
106+ return matches ! (
107+ ident. to_string( ) . as_str( ) ,
108+ "i8" | "i16" | "i32" | "i64" | "i128" |
109+ "u8" | "u16" | "u32" | "u64" | "u128" |
110+ "isize" | "usize"
111+ ) ;
112+ }
113+ }
114+ false
115+ }
116+
135117fn handle_impl_block ( impl_block : ItemImpl ) -> TokenStream {
136118 let self_ty = & impl_block. self_ty ;
137119 let mut methods = Vec :: new ( ) ;
@@ -154,12 +136,22 @@ fn handle_impl_block(impl_block: ItemImpl) -> TokenStream {
154136 . filter_map ( |arg| match arg {
155137 FnArg :: Typed ( pat_type) => {
156138 let param = & pat_type. pat ;
139+ let ty = & pat_type. ty ;
157140 let ptr = syn:: Ident :: new ( & format ! ( "{}_ptr" , quote!( #param) ) , name. span ( ) ) ;
158- let deser = match & * pat_type. ty {
159- Type :: Path ( tp) if quote ! ( #tp) . to_string ( ) . contains ( "String" ) => quote ! ( read_string) ,
160- _ => quote ! ( read_bytes) ,
141+
142+ let deser = if let Type :: Path ( tp) = & * * ty {
143+ if quote ! ( #tp) . to_string ( ) . contains ( "String" ) {
144+ quote ! ( read_string( #ptr) )
145+ } else if is_integer_type ( ty) {
146+ quote ! ( #ty:: from_bytes( read_bytes( #ptr) ) )
147+ } else {
148+ quote ! ( read_bytes( #ptr) )
149+ }
150+ } else {
151+ quote ! ( read_bytes( #ptr) )
161152 } ;
162- Some ( ( quote ! ( #ptr: i32 ) , quote ! ( let #param = #deser( #ptr) ; ) , quote ! ( #param) ) )
153+
154+ Some ( ( quote ! ( #ptr: i32 ) , quote ! ( let #param = #deser; ) , quote ! ( #param) ) )
163155 }
164156 _ => None ,
165157 } )
@@ -184,19 +176,17 @@ fn handle_impl_block(impl_block: ItemImpl) -> TokenStream {
184176 let body = if has_return {
185177 quote ! {
186178 #( #deserializations) *
187- let mut state = #self_ty:: default ( ) ;
188- state. __init_lazy_fields( alloc:: vec:: Vec :: new( ) ) ;
179+ let mut state = <#self_ty as ContractState >:: with_prefix( alloc:: vec:: Vec :: new( ) ) ;
189180 let result = state. #call;
190- state. __flush_lazy_fields ( ) ;
181+ state. flush ( ) ;
191182 ret( result) ;
192183 }
193184 } else {
194185 quote ! {
195186 #( #deserializations) *
196- let mut state = #self_ty:: default ( ) ;
197- state. __init_lazy_fields( alloc:: vec:: Vec :: new( ) ) ;
187+ let mut state = <#self_ty as ContractState >:: with_prefix( alloc:: vec:: Vec :: new( ) ) ;
198188 state. #call;
199- state. __flush_lazy_fields ( ) ;
189+ state. flush ( ) ;
200190 }
201191 } ;
202192
@@ -228,10 +218,19 @@ fn handle_function(input: ItemFn) -> TokenStream {
228218 for arg in inputs. iter ( ) {
229219 if let FnArg :: Typed ( pat_type) = arg {
230220 let param = & pat_type. pat ;
221+ let ty = & pat_type. ty ;
231222 let ptr = syn:: Ident :: new ( & format ! ( "arg{}_ptr" , idx) , name. span ( ) ) ;
232- let deser = match & * pat_type. ty {
233- Type :: Path ( tp) if quote ! ( #tp) . to_string ( ) . contains ( "String" ) => quote ! ( read_string) ,
234- _ => quote ! ( read_bytes) ,
223+
224+ let deser = if let Type :: Path ( tp) = & * * ty {
225+ if quote ! ( #tp) . to_string ( ) . contains ( "String" ) {
226+ quote ! ( read_string( #ptr) )
227+ } else if is_integer_type ( ty) {
228+ quote ! ( #ty:: from_bytes( read_bytes( #ptr) ) )
229+ } else {
230+ quote ! ( read_bytes( #ptr) )
231+ }
232+ } else {
233+ quote ! ( read_bytes( #ptr) )
235234 } ;
236235
237236 if idx > 0 {
@@ -242,7 +241,7 @@ fn handle_function(input: ItemFn) -> TokenStream {
242241 call_args. extend ( quote ! ( #param) ) ;
243242 }
244243
245- deserializations. extend ( quote ! { let #param = #deser( #ptr ) ; } ) ;
244+ deserializations. extend ( quote ! { let #param = #deser; } ) ;
246245 idx += 1 ;
247246 }
248247 }
0 commit comments