@@ -32,22 +32,29 @@ pub(crate) fn contract_bindings(
3232 let error_codes = quote ! { :: std:: collections:: HashMap :: from( [ #( #error_codes) , * ] ) } ;
3333
3434 let methods_name = ident ( & format ! ( "{name}Methods" ) ) ;
35+ let contract_methods_name = ident ( & format ! ( "{name}MethodVariants" ) ) ;
3536
3637 let contract_functions = expand_functions ( & abi. functions ) ?;
38+ let constant_methods_code =
39+ generate_constant_methods_pattern ( & abi. functions , & contract_methods_name) ?;
3740
3841 let configuration_struct_name = ident ( & format ! ( "{name}Configurables" ) ) ;
3942 let constant_configuration_code =
4043 generate_code_for_configurable_constants ( & configuration_struct_name, & abi. configurables ) ?;
4144
4245 let code = quote ! {
4346 #[ derive( Debug , Clone ) ]
44- pub struct #name<A > {
47+ pub struct #name<A = ( ) > {
4548 contract_id: :: fuels:: types:: ContractId ,
4649 account: A ,
4750 log_decoder: :: fuels:: core:: codec:: LogDecoder ,
4851 encoder_config: :: fuels:: core:: codec:: EncoderConfig ,
4952 }
5053
54+ impl #name {
55+ pub const METHODS : #contract_methods_name = #contract_methods_name;
56+ }
57+
5158 impl <A > #name<A >
5259 {
5360 pub fn new(
@@ -126,13 +133,20 @@ pub(crate) fn contract_bindings(
126133 }
127134
128135 #constant_configuration_code
136+
137+ #constant_methods_code
129138 } ;
130139
131140 // All publicly available types generated above should be listed here.
132- let type_paths = [ name, & methods_name, & configuration_struct_name]
133- . map ( |type_name| TypePath :: new ( type_name) . expect ( "We know the given types are not empty" ) )
134- . into_iter ( )
135- . collect ( ) ;
141+ let type_paths = [
142+ name,
143+ & methods_name,
144+ & configuration_struct_name,
145+ & contract_methods_name,
146+ ]
147+ . map ( |type_name| TypePath :: new ( type_name) . expect ( "We know the given types are not empty" ) )
148+ . into_iter ( )
149+ . collect ( ) ;
136150
137151 Ok ( GeneratedCode :: new ( code, type_paths, no_std) )
138152}
@@ -179,6 +193,49 @@ pub(crate) fn expand_fn(abi_fun: &FullABIFunction) -> Result<TokenStream> {
179193 Ok ( generator. generate ( ) )
180194}
181195
196+ fn generate_constant_methods_pattern (
197+ functions : & [ FullABIFunction ] ,
198+ contract_methods_name : & Ident ,
199+ ) -> Result < TokenStream > {
200+ let method_descriptors = functions. iter ( ) . map ( |func| {
201+ let method_name = ident ( func. name ( ) ) ;
202+ let fn_name = func. name ( ) ;
203+ let fn_selector =
204+ proc_macro2:: Literal :: byte_string ( & crate :: utils:: encode_fn_selector ( fn_name) ) ;
205+
206+ quote ! {
207+ pub const fn #method_name( & self ) -> :: fuels:: types:: MethodDescriptor {
208+ :: fuels:: types:: MethodDescriptor {
209+ name: #fn_name,
210+ fn_selector: #fn_selector,
211+ }
212+ }
213+ }
214+ } ) ;
215+
216+ let all_methods = functions. iter ( ) . map ( |func| {
217+ let method_name = ident ( func. name ( ) ) ;
218+ quote ! { Self . #method_name( ) }
219+ } ) ;
220+
221+ let method_count = functions. len ( ) ;
222+
223+ let code = quote ! {
224+ #[ derive( Debug , Clone , Copy ) ]
225+ pub struct #contract_methods_name;
226+
227+ impl #contract_methods_name {
228+ #( #method_descriptors) *
229+
230+ pub const fn iter( & self ) -> [ :: fuels:: types:: MethodDescriptor ; #method_count] {
231+ [ #( #all_methods) , * ]
232+ }
233+ }
234+ } ;
235+
236+ Ok ( code)
237+ }
238+
182239#[ cfg( test) ]
183240mod tests {
184241 use std:: collections:: HashMap ;
0 commit comments