Skip to content

Commit

Permalink
Merge pull request #51
Browse files Browse the repository at this point in the history
Added parsing from esdt attributes for generated structs and enums
  • Loading branch information
gfusee authored Nov 18, 2023
2 parents d1cd38b + ee89ca6 commit 17b1480
Show file tree
Hide file tree
Showing 17 changed files with 327 additions and 12 deletions.
64 changes: 63 additions & 1 deletion .novax/abis/tester-contract.abi.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"contractCrate": {
"name": "tester-contract",
"version": "0.0.0",
"gitVersion": "0.0.17-4-g302e541"
"gitVersion": "0.0.19-2-gfed15eb"
},
"framework": {
"name": "multiversx-sc",
Expand Down Expand Up @@ -59,6 +59,26 @@
}
]
},
{
"name": "returnNftEnumProperties",
"mutability": "mutable",
"inputs": [],
"outputs": [
{
"type": "TestEnumProperties"
}
]
},
{
"name": "returnNftEnumFieldsProperties",
"mutability": "mutable",
"inputs": [],
"outputs": [
{
"type": "TestEnumPropertiesWithFields"
}
]
},
{
"name": "returnFungibleBalance",
"mutability": "mutable",
Expand Down Expand Up @@ -714,6 +734,48 @@
}
]
},
"TestEnumProperties": {
"type": "enum",
"variants": [
{
"name": "First",
"discriminant": 0
},
{
"name": "Second",
"discriminant": 1,
"fields": [
{
"name": "0",
"type": "bytes"
},
{
"name": "1",
"type": "BigUint"
}
]
}
]
},
"TestEnumPropertiesWithFields": {
"type": "enum",
"variants": [
{
"name": "First",
"discriminant": 0,
"fields": [
{
"name": "buffer_value",
"type": "bytes"
},
{
"name": "integer",
"type": "BigUint"
}
]
}
]
},
"TestTokenProperties": {
"type": "struct",
"fields": [
Expand Down
Binary file modified .novax/tester-contract.wasm
Binary file not shown.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions abi-build/src/generator/impl_abi_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ fn get_mod_imports() -> TokenStream {
use multiversx_sdk::data::vm::VmValueRequest;
use serde::{Deserialize, Serialize};
use crate::errors::NovaXError;
use crate::errors::CodingError;
use crate::caching::CachingStrategy;
use crate::caching::CachingNone;
use std::collections::hash_map::DefaultHasher;
Expand Down
48 changes: 48 additions & 0 deletions abi-build/src/generator/impl_abi_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,30 @@ fn impl_abi_enum_type(name: &String, abi_type: &AbiType, all_abi_types: &AbiType
#native_values
}

impl #native_name_ident {
/// Constructs an instance of `#native_name_ident` from ESDT token attributes.
///
/// This function attempts to decode the provided ESDT attributes into an instance of `#native_name_ident`.
/// It is specifically designed to work with the attributes associated with ESDT tokens, which are typically
/// encoded in a binary format.
///
/// # Arguments
/// - `attributes`: A byte slice (`&[u8]`) representing the ESDT token attributes to be decoded.
///
/// # Returns
/// - `Ok(#native_name_ident)`: Successfully decoded instance of `#native_name_ident`.
/// - `Err(NovaXError)`: An error wrapped in `NovaXError`, specifically `CodingError::CannotDecodeEsdtAttributes`,
/// if the decoding process fails. This error indicates that the provided attributes could not be properly
/// decoded into the expected `#native_name_ident` type.
pub fn from_esdt_attributes(attributes: &[u8]) -> Result<#native_name_ident, NovaXError> {
let Result::Ok(decoded) = #managed_name_ident::top_decode(attributes) else {
return Result::Err(CodingError::CannotDecodeEsdtAttributes.into());
};

Result::Ok(decoded.to_native())
}
}

#native_convertible_impl

#managed_convertible_impl
Expand Down Expand Up @@ -340,6 +364,30 @@ fn impl_abi_struct_type(name: &str, abi_type: &AbiType, all_abi_types: &AbiTypes
/// Type alias for wrapping the managed API.
type #managed_name_type_wrap_api = #managed_name_ident;

impl #native_name_ident {
/// Constructs an instance of `#native_name_ident` from ESDT token attributes.
///
/// This function attempts to decode the provided ESDT attributes into an instance of `#native_name_ident`.
/// It is specifically designed to work with the attributes associated with ESDT tokens, which are typically
/// encoded in a binary format.
///
/// # Arguments
/// - `attributes`: A byte slice (`&[u8]`) representing the ESDT token attributes to be decoded.
///
/// # Returns
/// - `Ok(#native_name_ident)`: Successfully decoded instance of `#native_name_ident`.
/// - `Err(NovaXError)`: An error wrapped in `NovaXError`, specifically `CodingError::CannotDecodeEsdtAttributes`,
/// if the decoding process fails. This error indicates that the provided attributes could not be properly
/// decoded into the expected `#native_name_ident` type.
pub fn from_esdt_attributes(attributes: &[u8]) -> Result<#native_name_ident, NovaXError> {
let Result::Ok(decoded) = #managed_name_ident::top_decode(attributes) else {
return Result::Err(CodingError::CannotDecodeEsdtAttributes.into());
};

Result::Ok(decoded.to_native())
}
}

/// Provides a mechanism for converting a `#native_name_ident` to its managed representation (`#managed_name_ident`).
impl ManagedConvertible<#managed_name_ident> for #native_name_ident {
/// Converts the `#native_name_ident` to its managed representation.
Expand Down
37 changes: 37 additions & 0 deletions core/src/errors/coding_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use serde::{Deserialize, Serialize};
use crate::errors::novax_error::NovaXError;

/// Enumerates coding-related errors, specifically for encoding and decoding processes.
///
/// This enum represents errors that can occur during the encoding and decoding stages, particularly
/// involving serialization and deserialization of data structures used within the NovaX framework.
///
/// # Variants
/// - `CannotDecodeEsdtAttributes`: This error occurs when there's a failure in decoding attributes
/// associated with an ESDT (Elrond Standard Digital Token). While attributes are typically found in
/// non-fungible tokens (NFTs), this error covers scenarios where decoding such attributes fails for
/// any ESDT, fungible or non-fungible.
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
pub enum CodingError {
/// Represents an error that occurs when the decoding of attributes for an ESDT (Elrond Standard Digital Token)
/// fails. This error is particularly significant in the context of non-fungible tokens (NFTs), where attributes
/// play a crucial role in defining the token's properties and metadata.
CannotDecodeEsdtAttributes,
}

impl From<CodingError> for NovaXError {
/// Converts a `CodingError` into a `NovaXError`.
///
/// This implementation enables the seamless transformation of a specific coding error into the broader
/// `NovaXError` type. This is particularly useful for error handling strategies that require a consistent
/// error type across different modules of the NovaX framework.
///
/// # Arguments
/// - `value`: The `CodingError` instance to be converted.
///
/// # Returns
/// A `NovaXError` instance, specifically as a `NovaXError::Coding` variant containing the original `CodingError`.
fn from(value: CodingError) -> Self {
NovaXError::Coding(value)
}
}
4 changes: 3 additions & 1 deletion core/src/errors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ mod caching_error;
mod date_error;
mod account_error;
mod code_error;
mod coding_error;

pub use novax_error::NovaXError;
pub use caching_error::CachingError;
pub use date_error::DateError;
pub use account_error::AccountError;
pub use code_error::CodeError;
pub use code_error::CodeError;
pub use coding_error::CodingError;
5 changes: 5 additions & 0 deletions core/src/errors/novax_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use novax_executor::ExecutorError;
use crate::errors::account_error::AccountError;
use crate::errors::caching_error::CachingError;
use crate::errors::code_error::CodeError;
use crate::errors::CodingError;
use crate::errors::date_error::DateError;

/// The main error type for the `novax` crate.
Expand All @@ -20,6 +21,10 @@ pub enum NovaXError {
Date(DateError),
/// Errors related to fetching or parsing account information.
Account(AccountError),
/// Errors occurring during the encoding or decoding of managed types. This variant encompasses issues
/// related to serialization and deserialization processes, which are fundamental in ensuring data
/// integrity and adherence to expected formats.
Coding(CodingError),
/// Errors related to reading contract code from a file.
Code(CodeError),
}
Expand Down
2 changes: 1 addition & 1 deletion mocking/src/world/infos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ async fn get_addresses_balances(gateway_url: &str, addresses: &[Address]) -> Res
token_identifier: parse_token_identifier(&infos.token_identifier),
nonce: infos.nonce,
amount: infos.balance,
opt_attributes: infos.attributes.map(|e| e.as_bytes().to_vec())
opt_attributes: infos.attributes
})
}

Expand Down
27 changes: 27 additions & 0 deletions tester/contract/src/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ pub struct TestTokenProperties<M: ManagedTypeApi> {
pub integer: BigUint<M>
}

#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi)]
pub enum TestEnumProperties<M: ManagedTypeApi> {
First,
Second(ManagedBuffer<M>, BigUint<M>),
}

#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi)]
pub enum TestEnumPropertiesWithFields<M: ManagedTypeApi> {
First { buffer_value: ManagedBuffer<M>, integer: BigUint<M> },
}

#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi)]
pub struct CustomStruct<M: ManagedTypeApi> {
pub first: ManagedBuffer<M>,
Expand Down Expand Up @@ -50,6 +61,22 @@ pub trait PrinterModule: ContractBase {
)
}

#[endpoint(returnNftEnumProperties)]
fn return_nft_enum_properties(&self) -> TestEnumProperties<Self::Api> {
self.blockchain().get_token_attributes(
&TokenIdentifier::from("NFT-abcdef"),
6
)
}

#[endpoint(returnNftEnumFieldsProperties)]
fn return_nft_enum_fields_properties(&self) -> TestEnumPropertiesWithFields<Self::Api> {
self.blockchain().get_token_attributes(
&TokenIdentifier::from("NFT-abcdef"),
6
)
}

#[endpoint(returnFungibleBalance)]
fn return_fungible_balance(&self) -> BigUint<Self::Api> {
self.blockchain().get_sc_balance(
Expand Down
6 changes: 4 additions & 2 deletions tester/contract/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
////////////////////////////////////////////////////

// Init: 1
// Endpoints: 45
// Endpoints: 47
// Async Callback: 1
// Total number of exported functions: 47
// Total number of exported functions: 49

#![no_std]

Expand All @@ -25,6 +25,8 @@ multiversx_sc_wasm_adapter::endpoints! {
getSum => sum
add => add
returnNftProperties => return_nft_properties
returnNftEnumProperties => return_nft_enum_properties
returnNftEnumFieldsProperties => return_nft_enum_fields_properties
returnFungibleBalance => return_fungible_balance
returnNonFungibleBalance => return_non_fungible_balance
noArgNoReturnEndpoint => no_arg_no_return_endpoint
Expand Down
1 change: 1 addition & 0 deletions tester/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ hex = "0.4.3"
tester-contract = { path = "../contract" }
novax = { path = "../../core" }
novax-mocking = { path = "../../mocking" }
base64 = "0.21.5"

[package.metadata.release]
release = false
4 changes: 2 additions & 2 deletions tester/core/tests/dummy_deploy.rs

Large diffs are not rendered by default.

Loading

0 comments on commit 17b1480

Please sign in to comment.