I’ve got the following contract in sway which implements the SRC7 standard:
contract;
use src_7::{Metadata, SRC7};
use std::{call_frames::contract_id, hash::Hash, storage::storage_string::*, string::String};
impl SRC7 for Contract {
#[storage(read)]
fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
if key == String::from_ascii_str("key") {
Some(Metadata::String(String::from_ascii_str("value")))
} else {
None
}
}
}
And when I’m trying to call the metadata function from rust, I’m getting the following error: “Enums currently support only one level deep heap types”. Looks like the rust sdk doesn’t support nested enums, and in the current context both Option and Metadata are enums, nested one into each other in the return parameter of the function.
The way I’m calling the function:
let meta = contract_instance
.methods()
.metadata(asset_id, "key".to_string())
.simulate()
.await
.unwrap();
And the error I’m getting:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: InvalidType("Enums currently support only one level deep heap types.")
Can you please post a full detail of the enum you are using? We fortunately support nested enums, what we don’t support is “heap types” (ie vectors) nested at depth more than 1.
Ok so basically it’s because you’re returning an Option<Metadata>. If you were to return a Metadata it would work, because then the Bytes variant of the Metadata type is at depth one. I’m not sure what to advise you here.
It’s not me returning Option<Metadata>, it’s a Fuel’s standard that does this I’m just trying to follow the standard. Maybe you could communicate it within Fuel and change the standard appropriately?
PS: also, I tried to remove the Option wrapper and I was getting another error related to the rust sdk. I’ll give you details later
let result: Option<Enum<String>> = SRC7.metadata(myAsset, myKey);
Considering:
/// Universal return type for metadata.
pub enum Metadata {
// Used when the stored metadata is a `b256`.
B256: b256,
/// Used when the stored metadata is `Bytes`.
Bytes: Bytes,
/// Used when the stored metadata is a `u64`.
Int: u64,
/// Used when the stored metadata is a `String`.
String: String,
}