use serde::{Deserialize, Serialize, de::DeserializeOwned};
use tari_template_abi::{EngineOp, call_engine, rust::vec};
use tari_template_lib_types::NonFungibleAddress;
use crate::{
args::{InvokeResult, NonFungibleAction, NonFungibleInvokeArg},
resource::ResourceManager,
};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(transparent)]
pub struct NonFungible {
address: NonFungibleAddress,
}
impl NonFungible {
pub fn new(address: NonFungibleAddress) -> Self {
Self { address }
}
pub fn get_data<T: DeserializeOwned>(&self) -> T {
let resp: InvokeResult = call_engine(EngineOp::NonFungibleInvoke, &NonFungibleInvokeArg {
address: self.address.clone(),
action: NonFungibleAction::GetData,
args: vec![],
});
resp.decode().expect("[get_data] Failed to decode NonFungible data")
}
pub fn get_mutable_data<T: DeserializeOwned>(&self) -> T {
let resp: InvokeResult = call_engine(EngineOp::NonFungibleInvoke, &NonFungibleInvokeArg {
address: self.address.clone(),
action: NonFungibleAction::GetMutableData,
args: vec![],
});
resp.decode()
.expect("[get_mutable_data] Failed to decode raw NonFungible mutable data")
}
pub fn set_mutable_data<T: Serialize + ?Sized>(&mut self, data: &T) {
ResourceManager::get(*self.address.resource_address())
.update_non_fungible_data(self.address.id().clone(), data);
}
}