Skip to content

Commit

Permalink
Merge pull request #1819 from multiversx/endpoint-abi-builder
Browse files Browse the repository at this point in the history
abi - EndpointAbi builder pattern
  • Loading branch information
andrei-marinica authored Oct 14, 2024
2 parents f2e5d28 + 53a64a0 commit 46d9bc8
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 69 deletions.
59 changes: 42 additions & 17 deletions framework/base/src/abi/endpoint_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: TypeAbi>(&mut self, arg_name: &str) {
self.inputs.push(InputAbi {
arg_name: arg_name.to_string(),
Expand Down
16 changes: 4 additions & 12 deletions framework/base/src/external_view_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
40 changes: 29 additions & 11 deletions framework/derive/src/generate/abi_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<proc_macro2::TokenStream> = m
Expand Down Expand Up @@ -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
}
Expand Down
31 changes: 2 additions & 29 deletions framework/scenario/tests/contract_without_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<
Expand All @@ -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::<multiversx_sc::types::BigUint<Self::Api>>("initial_value");
contract_abi.add_type_descriptions::<multiversx_sc::types::BigUint<Self::Api>>();
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::<multiversx_sc::types::BigUint<Self::Api>>("initial_value");
contract_abi.add_type_descriptions::<multiversx_sc::types::BigUint<Self::Api>>();
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::<multiversx_sc::types::BigUint<Self::Api>>("value");
contract_abi.add_type_descriptions::<multiversx_sc::types::BigUint<Self::Api>>();
contract_abi.endpoints.push(endpoint_abi);
Expand Down

0 comments on commit 46d9bc8

Please sign in to comment.