11use std:: fs:: File ;
22use std:: io:: Write ;
33
4- use multiversx_sc:: abi:: { ContractAbi , EndpointAbi , EndpointMutabilityAbi , InputAbi } ;
5- use serde:: Deserialize ;
4+ use multiversx_sc:: abi:: { ContractAbi , EndpointAbi , InputAbi , OutputAbi } ;
5+ use serde:: de:: DeserializeOwned ;
6+ use serde:: { de, Deserialize , Deserializer } ;
67
78use crate :: abi_json:: { serialize_abi_to_json, ContractAbiJson } ;
89
910use super :: snippet_crate_gen:: LIB_SOURCE_FILE_NAME ;
10- use super :: snippet_sc_functions_gen:: endpoint_args_when_called;
1111use super :: snippet_type_map:: map_abi_type_to_rust_type;
1212use crate :: contract:: generate_snippets:: snippet_sc_functions_gen:: DEFAULT_GAS ;
1313
14- #[ derive( PartialEq , Deserialize , Clone ) ]
14+ #[ derive( PartialEq , Deserialize , Clone , Debug ) ]
1515#[ serde( rename_all = "camelCase" ) ]
1616pub ( crate ) struct ShortContractAbi {
1717 #[ serde( default ) ]
1818 pub name : String ,
19+ #[ serde( default , deserialize_with = "deserialize_single_or_vec" ) ]
20+ pub constructor : Vec < ShortEndpointAbi > ,
21+ #[ serde(
22+ default ,
23+ rename = "upgradeConstructor" ,
24+ deserialize_with = "deserialize_single_or_vec"
25+ ) ]
26+ pub upgrade_constructor : Vec < ShortEndpointAbi > ,
1927 #[ serde( default ) ]
20- pub constructors : Vec < EndpointAbi > ,
21- #[ serde( default , rename = "upgradeConstructor" ) ]
22- pub upgrade_constructors : Vec < EndpointAbi > ,
23- pub endpoints : Vec < EndpointAbi > ,
28+ pub endpoints : Vec < ShortEndpointAbi > ,
29+ }
30+
31+ #[ derive( PartialEq , Deserialize , Clone , Debug ) ]
32+ pub ( crate ) struct ShortEndpointAbi {
33+ #[ serde( default ) ]
34+ pub name : String ,
35+ #[ serde( default ) ]
36+ pub mutability : String ,
37+ #[ serde( default , skip_deserializing) ]
38+ pub rust_method_name : String ,
39+ #[ serde( default ) ]
40+ pub payable_in_tokens : Vec < String > ,
41+ #[ serde( default ) ]
42+ pub inputs : Vec < ShortInputAbi > ,
43+ #[ serde( default ) ]
44+ pub outputs : Vec < ShortOutputAbi > ,
45+ #[ serde( default ) ]
46+ pub allow_multiple_var_args : bool ,
47+ }
48+
49+ #[ derive( PartialEq , Deserialize , Clone , Debug ) ]
50+ pub ( crate ) struct ShortInputAbi {
51+ #[ serde( default ) ]
52+ pub name : String ,
53+ #[ serde( rename = "type" ) ]
54+ pub type_name : String ,
55+ #[ serde( default ) ]
56+ pub multi_arg : bool ,
57+ }
58+
59+ #[ derive( PartialEq , Deserialize , Clone , Debug ) ]
60+ pub ( crate ) struct ShortOutputAbi {
61+ #[ serde( rename = "type" ) ]
62+ pub type_name : String ,
63+ #[ serde( default ) ]
64+ pub multi_result : bool ,
65+ }
66+
67+ fn deserialize_single_or_vec < ' de , D , T > ( deserializer : D ) -> Result < Vec < T > , D :: Error >
68+ where
69+ D : Deserializer < ' de > ,
70+ T : DeserializeOwned ,
71+ {
72+ let value = serde_json:: Value :: deserialize ( deserializer) ?;
73+ match value {
74+ serde_json:: Value :: Array ( vec) => {
75+ serde_json:: from_value ( serde_json:: Value :: Array ( vec) ) . map_err ( de:: Error :: custom)
76+ } ,
77+ _ => Ok ( serde_json:: from_value ( value. clone ( ) )
78+ . map ( |single| vec ! [ single] )
79+ . expect ( & format ! ( "error at {value:?}" ) ) ) , // .map_err(de::Error::custom),
80+ }
81+ }
82+
83+ impl From < EndpointAbi > for ShortEndpointAbi {
84+ fn from ( value : EndpointAbi ) -> Self {
85+ Self {
86+ name : value. name ,
87+ mutability : format ! ( "{:?}" , value. mutability) . to_lowercase ( ) ,
88+ rust_method_name : value. rust_method_name ,
89+ payable_in_tokens : value. payable_in_tokens ,
90+ inputs : value. inputs . into_iter ( ) . map ( ShortInputAbi :: from) . collect ( ) ,
91+ outputs : value
92+ . outputs
93+ . into_iter ( )
94+ . map ( ShortOutputAbi :: from)
95+ . collect ( ) ,
96+ allow_multiple_var_args : value. allow_multiple_var_args ,
97+ }
98+ }
99+ }
100+
101+ impl From < InputAbi > for ShortInputAbi {
102+ fn from ( value : InputAbi ) -> Self {
103+ Self {
104+ name : value. arg_name ,
105+ type_name : value. type_names . abi ,
106+ multi_arg : value. multi_arg ,
107+ }
108+ }
109+ }
110+
111+ impl From < OutputAbi > for ShortOutputAbi {
112+ fn from ( value : OutputAbi ) -> Self {
113+ Self {
114+ type_name : value. type_names . abi ,
115+ multi_result : value. multi_result ,
116+ }
117+ }
24118}
25119
26120impl From < ContractAbi > for ShortContractAbi {
27121 fn from ( value : ContractAbi ) -> Self {
28122 Self {
29123 name : value. name ,
30- constructors : value. constructors ,
31- upgrade_constructors : value. upgrade_constructors ,
32- endpoints : value. endpoints ,
124+ constructor : value
125+ . constructors
126+ . into_iter ( )
127+ . map ( ShortEndpointAbi :: from)
128+ . collect ( ) ,
129+ upgrade_constructor : value
130+ . upgrade_constructors
131+ . into_iter ( )
132+ . map ( ShortEndpointAbi :: from)
133+ . collect ( ) ,
134+ endpoints : value
135+ . endpoints
136+ . into_iter ( )
137+ . map ( ShortEndpointAbi :: from)
138+ . collect ( ) ,
33139 }
34140 }
35141}
@@ -47,23 +153,23 @@ pub(crate) fn check_abi_differences(
47153 if let Ok ( prev_abi) = serde_json:: from_str :: < ShortContractAbi > ( & prev_abi_content) {
48154 let mut diff_abi = ShortContractAbi {
49155 name : current_contract_abi. name . clone ( ) ,
50- constructors : vec ! [ ] ,
51- upgrade_constructors : vec ! [ ] ,
156+ constructor : vec ! [ ] ,
157+ upgrade_constructor : vec ! [ ] ,
52158 endpoints : vec ! [ ] ,
53159 } ;
54160
55161 // changed and new constructors
56- for constructor in & current_contract_abi. constructors {
57- if !prev_abi. constructors . contains ( constructor) {
58- diff_abi. constructors . push ( constructor. clone ( ) ) ;
162+ for constructor in & current_contract_abi. constructor {
163+ if !prev_abi. constructor . contains ( constructor) {
164+ diff_abi. constructor . push ( constructor. clone ( ) ) ;
59165 }
60166 }
61167
62168 // changed and new upgrade constructors
63- for upgrade_constructor in & current_contract_abi. upgrade_constructors {
64- if !prev_abi. upgrade_constructors . contains ( upgrade_constructor) {
169+ for upgrade_constructor in & current_contract_abi. upgrade_constructor {
170+ if !prev_abi. upgrade_constructor . contains ( upgrade_constructor) {
65171 diff_abi
66- . upgrade_constructors
172+ . upgrade_constructor
67173 . push ( upgrade_constructor. clone ( ) ) ;
68174 }
69175 }
@@ -76,13 +182,17 @@ pub(crate) fn check_abi_differences(
76182 }
77183
78184 // deleted endpoints
185+ // bug here when deleting and diff with no overwrite
79186 for endpoint in & prev_abi. endpoints {
80187 if !current_contract_abi. endpoints . contains ( endpoint) {
81188 diff_abi. endpoints . retain ( |e| e. name != endpoint. name ) ;
82189 }
83190 }
84191
192+ println ! ( "diff_abi {diff_abi:?}" ) ;
85193 return diff_abi;
194+ } else {
195+ println ! ( "here" )
86196 }
87197 }
88198 }
@@ -99,7 +209,7 @@ pub(crate) fn create_prev_abi_file(snippets_dir: &String, contract_abi: &Contrac
99209}
100210
101211pub ( crate ) fn add_new_endpoints_to_file ( snippets_dir : & String , diff_abi : & ShortContractAbi ) {
102- let interact_lib_path = format ! ( "{snippets_dir}/{LIB_SOURCE_FILE_NAME}" ) ;
212+ let interact_lib_path = format ! ( "{snippets_dir}/src/ {LIB_SOURCE_FILE_NAME}" ) ;
103213 let file_content = std:: fs:: read_to_string ( & interact_lib_path) . unwrap ( ) ;
104214 let mut updated_content = file_content. clone ( ) ;
105215
@@ -108,21 +218,22 @@ pub(crate) fn add_new_endpoints_to_file(snippets_dir: &String, diff_abi: &ShortC
108218 insert_or_replace_function ( & updated_content, endpoint_abi, & diff_abi. name ) ;
109219 }
110220
111- for constructor in & diff_abi. constructors {
221+ for constructor in & diff_abi. constructor {
112222 updated_content = insert_or_replace_function ( & updated_content, constructor, & diff_abi. name ) ;
113223 }
114224
115- for upgrade_constructor in & diff_abi. upgrade_constructors {
225+ for upgrade_constructor in & diff_abi. upgrade_constructor {
116226 updated_content =
117227 insert_or_replace_function ( & updated_content, upgrade_constructor, & diff_abi. name ) ;
118228 }
119229
120230 std:: fs:: write ( interact_lib_path, updated_content) . unwrap ( ) ;
121231}
122232
233+ // this may be buggy
123234fn insert_or_replace_function (
124235 file_content : & str ,
125- endpoint_abi : & EndpointAbi ,
236+ endpoint_abi : & ShortEndpointAbi ,
126237 contract_name : & String ,
127238) -> String {
128239 let function_signature = format ! ( "pub async fn {}" , endpoint_abi. rust_method_name) ;
@@ -163,14 +274,14 @@ fn insert_or_replace_function(
163274
164275pub ( crate ) fn write_endpoint_impl_to_string (
165276 buffer : & mut String ,
166- endpoint_abi : & EndpointAbi ,
277+ endpoint_abi : & ShortEndpointAbi ,
167278 name : & String ,
168279) {
169280 write_method_declaration_to_string ( buffer, & endpoint_abi. rust_method_name ) ;
170281 write_payments_declaration_to_string ( buffer, & endpoint_abi. payable_in_tokens ) ;
171282 write_endpoint_args_declaration_to_string ( buffer, & endpoint_abi. inputs ) ;
172283
173- if matches ! ( endpoint_abi. mutability, EndpointMutabilityAbi :: Readonly ) {
284+ if endpoint_abi. mutability == "readonly" . to_string ( ) {
174285 write_contract_query_to_string ( buffer, endpoint_abi, name) ;
175286 } else {
176287 write_contract_call_to_string ( buffer, endpoint_abi, name) ;
@@ -206,31 +317,35 @@ pub(crate) fn write_payments_declaration_to_string(
206317 let token_nonce = 0u64;
207318 let token_amount = " ,
208319 ) ;
209- buffer. push_str ( & biguint_default. get_default_value_expr ( ) ) ;
320+ buffer. push_str ( biguint_default. get_default_value_expr ( ) ) ;
210321 buffer. push_str ( ";\n " ) ;
211322 }
212323
213324 buffer. push ( '\n' ) ;
214325}
215326
216- fn write_endpoint_args_declaration_to_string ( buffer : & mut String , inputs : & [ InputAbi ] ) {
327+ fn write_endpoint_args_declaration_to_string ( buffer : & mut String , inputs : & [ ShortInputAbi ] ) {
217328 if inputs. is_empty ( ) {
218329 return ;
219330 }
220331
221332 for input in inputs {
222- let rust_type = map_abi_type_to_rust_type ( input. type_names . abi . clone ( ) ) ;
333+ let rust_type = map_abi_type_to_rust_type ( input. type_name . clone ( ) ) ;
223334 buffer. push_str ( & format ! (
224335 " let {} = {};\n " ,
225- input. arg_name ,
336+ input. name ,
226337 rust_type. get_default_value_expr( )
227338 ) ) ;
228339 }
229340
230341 buffer. push ( '\n' ) ;
231342}
232343
233- fn write_contract_call_to_string ( buffer : & mut String , endpoint_abi : & EndpointAbi , name : & String ) {
344+ fn write_contract_call_to_string (
345+ buffer : & mut String ,
346+ endpoint_abi : & ShortEndpointAbi ,
347+ name : & String ,
348+ ) {
234349 let payment_snippet = if endpoint_abi. payable_in_tokens . is_empty ( ) {
235350 "" . to_string ( )
236351 } else if endpoint_abi. payable_in_tokens [ 0 ] == "EGLD" {
@@ -256,12 +371,16 @@ fn write_contract_call_to_string(buffer: &mut String, endpoint_abi: &EndpointAbi
256371"# ,
257372 name,
258373 endpoint_abi. rust_method_name,
259- endpoint_args_when_called ( endpoint_abi. inputs. as_slice( ) ) ,
374+ endpoint_args_when_called_short ( endpoint_abi. inputs. as_slice( ) ) ,
260375 payment_snippet,
261376 ) ) ;
262377}
263378
264- fn write_contract_query_to_string ( buffer : & mut String , endpoint_abi : & EndpointAbi , name : & String ) {
379+ fn write_contract_query_to_string (
380+ buffer : & mut String ,
381+ endpoint_abi : & ShortEndpointAbi ,
382+ name : & String ,
383+ ) {
265384 buffer. push_str ( & format ! (
266385 r#" let result_value = self
267386 .interactor
@@ -277,6 +396,17 @@ fn write_contract_query_to_string(buffer: &mut String, endpoint_abi: &EndpointAb
277396"# ,
278397 name,
279398 endpoint_abi. rust_method_name,
280- endpoint_args_when_called ( endpoint_abi. inputs. as_slice( ) ) ,
399+ endpoint_args_when_called_short ( endpoint_abi. inputs. as_slice( ) ) ,
281400 ) ) ;
282401}
402+
403+ pub ( crate ) fn endpoint_args_when_called_short ( inputs : & [ ShortInputAbi ] ) -> String {
404+ let mut result = String :: new ( ) ;
405+ for input in inputs {
406+ if !result. is_empty ( ) {
407+ result. push_str ( ", " ) ;
408+ }
409+ result. push_str ( & input. name ) ;
410+ }
411+ result
412+ }
0 commit comments