diff --git a/framework/base/src/abi/endpoint_abi.rs b/framework/base/src/abi/endpoint_abi.rs index c1d0567643..8e96554d84 100644 --- a/framework/base/src/abi/endpoint_abi.rs +++ b/framework/base/src/abi/endpoint_abi.rs @@ -57,39 +57,64 @@ pub struct EndpointAbi { impl EndpointAbi { /// Used in code generation. - /// - /// TODO: replace with builder pattern to gt rid of the too many arguments. - #[allow(clippy::too_many_arguments)] pub fn new( - docs: &[&str], name: &str, rust_method_name: &str, - title: Option<&str>, - only_owner: bool, - only_admin: bool, mutability: EndpointMutabilityAbi, endpoint_type: EndpointTypeAbi, - payable_in_tokens: &[&str], - labels: &[&str], - allow_multiple_var_args: bool, ) -> Self { EndpointAbi { - docs: docs.iter().map(|s| s.to_string()).collect(), + docs: Vec::new(), name: name.to_string(), rust_method_name: rust_method_name.to_string(), - only_owner, - only_admin, - labels: labels.iter().map(|s| s.to_string()).collect(), + only_owner: false, + only_admin: false, + labels: Vec::new(), endpoint_type, mutability, - payable_in_tokens: payable_in_tokens.iter().map(|s| s.to_string()).collect(), - title: title.map(|title| title.to_owned()), + payable_in_tokens: Vec::new(), + title: None, inputs: Vec::new(), outputs: Vec::new(), - allow_multiple_var_args, + allow_multiple_var_args: false, } } + pub fn with_docs(mut self, doc_line: &str) -> Self { + self.docs.push(doc_line.to_owned()); + self + } + + pub fn with_title(mut self, title: &str) -> Self { + self.title = Some(title.to_owned()); + self + } + + pub fn with_only_owner(mut self) -> Self { + self.only_owner = true; + self + } + + pub fn with_only_admin(mut self) -> Self { + self.only_admin = true; + self + } + + pub fn with_allow_multiple_var_args(mut self) -> Self { + self.allow_multiple_var_args = true; + self + } + + pub fn with_label(mut self, label: &str) -> Self { + self.labels.push(label.to_owned()); + self + } + + pub fn with_payable_token(mut self, token: &str) -> Self { + self.payable_in_tokens.push(token.to_owned()); + self + } + pub fn add_input(&mut self, arg_name: &str) { self.inputs.push(InputAbi { arg_name: arg_name.to_string(), diff --git a/framework/base/src/external_view_contract.rs b/framework/base/src/external_view_contract.rs index 7a1e0722a7..4388e74618 100644 --- a/framework/base/src/external_view_contract.rs +++ b/framework/base/src/external_view_contract.rs @@ -32,22 +32,14 @@ where /// The definition for the external view pub fn external_view_contract_constructor_abi() -> EndpointAbi { let mut endpoint_abi = EndpointAbi::new( - &[ - "The external view init prepares a contract that looks in another contract's storage.", - "It takes a single argument, the other contract's address", - "You won't find this constructors' definition in the contract, it gets injected automatically by the framework. See `multiversx_sc::external_view_contract`.", - ], "init", EXTERNAL_VIEW_CONSTRUCTOR_FLAG, - None, - false, - false, EndpointMutabilityAbi::Mutable, EndpointTypeAbi::Init, - &[], - &[], - false - ); + ) + .with_docs("The external view init prepares a contract that looks in another contract's storage.") + .with_docs("It takes a single argument, the other contract's address") + .with_docs("You won't find this constructors' definition in the contract, it gets injected automatically by the framework. See `multiversx_sc::external_view_contract`."); endpoint_abi.inputs.push(InputAbi { arg_name: "target_contract_address".to_string(), type_names: crate::types::heap::Address::type_names(), diff --git a/framework/derive/src/generate/abi_gen.rs b/framework/derive/src/generate/abi_gen.rs index db727cf7c4..0aa70fbc06 100644 --- a/framework/derive/src/generate/abi_gen.rs +++ b/framework/derive/src/generate/abi_gen.rs @@ -15,11 +15,27 @@ fn generate_endpoint_snippet( ) -> proc_macro2::TokenStream { let endpoint_docs = &m.docs; let rust_method_name = m.name.to_string(); - let title_tokens = if let Some(title) = &m.title { - quote! { Some(#title) } + let title_tokens = m + .title + .as_ref() + .map(|title| quote! { .with_title(#title) }) + .unwrap_or_default(); + let only_owner_tokens = if only_owner { + quote! { .with_only_owner() } } else { - quote! { None } + quote! {} }; + let only_admin_tokens = if only_admin { + quote! { .with_only_admin() } + } else { + quote! {} + }; + let allow_multiple_var_args_tokens = if allow_multiple_var_args { + quote! { .with_allow_multiple_var_args() } + } else { + quote! {} + }; + let payable_in_tokens = m.payable_metadata().abi_strings(); let input_snippets: Vec = m @@ -60,18 +76,20 @@ fn generate_endpoint_snippet( quote! { let mut endpoint_abi = multiversx_sc::abi::EndpointAbi::new( - &[ #(#endpoint_docs),* ], #endpoint_name, #rust_method_name, - #title_tokens, - #only_owner, - #only_admin, #mutability_tokens, #endpoint_type_tokens, - &[ #(#payable_in_tokens),* ], - &[ #(#label_names),* ], - #allow_multiple_var_args, - ); + ) + #(.with_docs(#endpoint_docs))* + #title_tokens + #only_owner_tokens + #only_admin_tokens + #(.with_label(#label_names))* + #(.with_payable_token(#payable_in_tokens))* + #allow_multiple_var_args_tokens + ; + #(#input_snippets)* #output_snippet } diff --git a/framework/scenario/tests/contract_without_macros.rs b/framework/scenario/tests/contract_without_macros.rs index 7515365023..6d445d3fc4 100644 --- a/framework/scenario/tests/contract_without_macros.rs +++ b/framework/scenario/tests/contract_without_macros.rs @@ -387,17 +387,10 @@ mod sample_adder { false, ); let mut endpoint_abi = multiversx_sc::abi::EndpointAbi::new( - &[], "getSum", "sum", - None, - false, - false, multiversx_sc::abi::EndpointMutabilityAbi::Readonly, multiversx_sc::abi::EndpointTypeAbi::Endpoint, - &[], - &[], - false, ); endpoint_abi .add_output::< @@ -409,50 +402,30 @@ mod sample_adder { >(); contract_abi.endpoints.push(endpoint_abi); let mut endpoint_abi = multiversx_sc::abi::EndpointAbi::new( - &[], "init", "init", - None, - false, - false, multiversx_sc::abi::EndpointMutabilityAbi::Mutable, multiversx_sc::abi::EndpointTypeAbi::Init, - &[], - &[], - false, ); endpoint_abi.add_input::>("initial_value"); contract_abi.add_type_descriptions::>(); contract_abi.constructors.push(endpoint_abi); let mut endpoint_abi = multiversx_sc::abi::EndpointAbi::new( - &[], "upgrade", "upgrade", - None, - false, - false, multiversx_sc::abi::EndpointMutabilityAbi::Mutable, multiversx_sc::abi::EndpointTypeAbi::Upgrade, - &[], - &[], - false, ); endpoint_abi.add_input::>("initial_value"); contract_abi.add_type_descriptions::>(); contract_abi.upgrade_constructors.push(endpoint_abi); let mut endpoint_abi = multiversx_sc::abi::EndpointAbi::new( - &["Add desired amount to the storage variable."], "add", "add", - None, - false, - false, multiversx_sc::abi::EndpointMutabilityAbi::Mutable, multiversx_sc::abi::EndpointTypeAbi::Endpoint, - &[], - &[], - false, - ); + ) + .with_docs("Add desired amount to the storage variable."); endpoint_abi.add_input::>("value"); contract_abi.add_type_descriptions::>(); contract_abi.endpoints.push(endpoint_abi);