Nfts attribute read interface (#13349)

* feat: add custom and system attributes to Inspect

* feat: add nfts runtime api

* fix: pass std feature to runtime api

* fix: api copyright

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>

---------

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
This commit is contained in:
Daniel Shiposha
2023-02-23 15:06:12 +00:00
committed by GitHub
parent 2568c6d48b
commit 4af011f418
10 changed files with 291 additions and 30 deletions
@@ -25,10 +25,7 @@
//! use.
use super::nonfungibles_v2 as nonfungibles;
use crate::{
dispatch::DispatchResult,
traits::{tokens::misc::AttributeNamespace, Get},
};
use crate::{dispatch::DispatchResult, traits::Get};
use codec::{Decode, Encode};
use sp_runtime::TokenError;
use sp_std::prelude::*;
@@ -45,23 +42,53 @@ pub trait Inspect<AccountId> {
/// Returns the attribute value of `item` corresponding to `key`.
///
/// By default this is `None`; no attributes are defined.
fn attribute(
fn attribute(_item: &Self::ItemId, _key: &[u8]) -> Option<Vec<u8>> {
None
}
/// Returns the custom attribute value of `item` corresponding to `key`.
///
/// By default this is `None`; no attributes are defined.
fn custom_attribute(
_account: &AccountId,
_item: &Self::ItemId,
_namespace: &AttributeNamespace<AccountId>,
_key: &[u8],
) -> Option<Vec<u8>> {
None
}
/// Returns the system attribute value of `item` corresponding to `key`.
///
/// By default this is `None`; no attributes are defined.
fn system_attribute(_item: &Self::ItemId, _key: &[u8]) -> Option<Vec<u8>> {
None
}
/// Returns the strongly-typed attribute value of `item` corresponding to `key`.
///
/// By default this just attempts to use `attribute`.
fn typed_attribute<K: Encode, V: Decode>(
fn typed_attribute<K: Encode, V: Decode>(item: &Self::ItemId, key: &K) -> Option<V> {
key.using_encoded(|d| Self::attribute(item, d))
.and_then(|v| V::decode(&mut &v[..]).ok())
}
/// Returns the strongly-typed custom attribute value of `item` corresponding to `key`.
///
/// By default this just attempts to use `custom_attribute`.
fn typed_custom_attribute<K: Encode, V: Decode>(
account: &AccountId,
item: &Self::ItemId,
namespace: &AttributeNamespace<AccountId>,
key: &K,
) -> Option<V> {
key.using_encoded(|d| Self::attribute(item, namespace, d))
key.using_encoded(|d| Self::custom_attribute(account, item, d))
.and_then(|v| V::decode(&mut &v[..]).ok())
}
/// Returns the strongly-typed system attribute value of `item` corresponding to `key`.
///
/// By default this just attempts to use `system_attribute`.
fn typed_system_attribute<K: Encode, V: Decode>(item: &Self::ItemId, key: &K) -> Option<V> {
key.using_encoded(|d| Self::system_attribute(item, d))
.and_then(|v| V::decode(&mut &v[..]).ok())
}
@@ -167,19 +194,32 @@ impl<
fn owner(item: &Self::ItemId) -> Option<AccountId> {
<F as nonfungibles::Inspect<AccountId>>::owner(&A::get(), item)
}
fn attribute(
item: &Self::ItemId,
namespace: &AttributeNamespace<AccountId>,
key: &[u8],
) -> Option<Vec<u8>> {
<F as nonfungibles::Inspect<AccountId>>::attribute(&A::get(), item, namespace, key)
fn attribute(item: &Self::ItemId, key: &[u8]) -> Option<Vec<u8>> {
<F as nonfungibles::Inspect<AccountId>>::attribute(&A::get(), item, key)
}
fn typed_attribute<K: Encode, V: Decode>(
fn custom_attribute(account: &AccountId, item: &Self::ItemId, key: &[u8]) -> Option<Vec<u8>> {
<F as nonfungibles::Inspect<AccountId>>::custom_attribute(account, &A::get(), item, key)
}
fn system_attribute(item: &Self::ItemId, key: &[u8]) -> Option<Vec<u8>> {
<F as nonfungibles::Inspect<AccountId>>::system_attribute(&A::get(), item, key)
}
fn typed_attribute<K: Encode, V: Decode>(item: &Self::ItemId, key: &K) -> Option<V> {
<F as nonfungibles::Inspect<AccountId>>::typed_attribute(&A::get(), item, key)
}
fn typed_custom_attribute<K: Encode, V: Decode>(
account: &AccountId,
item: &Self::ItemId,
namespace: &AttributeNamespace<AccountId>,
key: &K,
) -> Option<V> {
<F as nonfungibles::Inspect<AccountId>>::typed_attribute(&A::get(), item, namespace, key)
<F as nonfungibles::Inspect<AccountId>>::typed_custom_attribute(
account,
&A::get(),
item,
key,
)
}
fn typed_system_attribute<K: Encode, V: Decode>(item: &Self::ItemId, key: &K) -> Option<V> {
<F as nonfungibles::Inspect<AccountId>>::typed_system_attribute(&A::get(), item, key)
}
fn can_transfer(item: &Self::ItemId) -> bool {
<F as nonfungibles::Inspect<AccountId>>::can_transfer(&A::get(), item)
@@ -27,10 +27,7 @@
//! Implementations of these traits may be converted to implementations of corresponding
//! `nonfungible` traits by using the `nonfungible::ItemOf` type adapter.
use crate::{
dispatch::{DispatchError, DispatchResult},
traits::tokens::misc::AttributeNamespace,
};
use crate::dispatch::{DispatchError, DispatchResult};
use codec::{Decode, Encode};
use sp_runtime::TokenError;
use sp_std::prelude::*;
@@ -61,7 +58,29 @@ pub trait Inspect<AccountId> {
fn attribute(
_collection: &Self::CollectionId,
_item: &Self::ItemId,
_namespace: &AttributeNamespace<AccountId>,
_key: &[u8],
) -> Option<Vec<u8>> {
None
}
/// Returns the custom attribute value of `item` of `collection` corresponding to `key`.
///
/// By default this is `None`; no attributes are defined.
fn custom_attribute(
_account: &AccountId,
_collection: &Self::CollectionId,
_item: &Self::ItemId,
_key: &[u8],
) -> Option<Vec<u8>> {
None
}
/// Returns the system attribute value of `item` of `collection` corresponding to `key`.
///
/// By default this is `None`; no attributes are defined.
fn system_attribute(
_collection: &Self::CollectionId,
_item: &Self::ItemId,
_key: &[u8],
) -> Option<Vec<u8>> {
None
@@ -74,10 +93,36 @@ pub trait Inspect<AccountId> {
fn typed_attribute<K: Encode, V: Decode>(
collection: &Self::CollectionId,
item: &Self::ItemId,
namespace: &AttributeNamespace<AccountId>,
key: &K,
) -> Option<V> {
key.using_encoded(|d| Self::attribute(collection, item, namespace, d))
key.using_encoded(|d| Self::attribute(collection, item, d))
.and_then(|v| V::decode(&mut &v[..]).ok())
}
/// Returns the strongly-typed custom attribute value of `item` of `collection` corresponding to
/// `key`.
///
/// By default this just attempts to use `custom_attribute`.
fn typed_custom_attribute<K: Encode, V: Decode>(
account: &AccountId,
collection: &Self::CollectionId,
item: &Self::ItemId,
key: &K,
) -> Option<V> {
key.using_encoded(|d| Self::custom_attribute(account, collection, item, d))
.and_then(|v| V::decode(&mut &v[..]).ok())
}
/// Returns the strongly-typed system attribute value of `item` of `collection` corresponding to
/// `key`.
///
/// By default this just attempts to use `system_attribute`.
fn typed_system_attribute<K: Encode, V: Decode>(
collection: &Self::CollectionId,
item: &Self::ItemId,
key: &K,
) -> Option<V> {
key.using_encoded(|d| Self::system_attribute(collection, item, d))
.and_then(|v| V::decode(&mut &v[..]).ok())
}