Skip to content
Snippets Groups Projects
Commit c30ece2b authored by Alexander Popiak's avatar Alexander Popiak Committed by GitHub
Browse files

Implement `InspectEnumerable` for Uniques (#9117)


* implement InspectEnumerable in pallet_uniques

* use `iter_keys` and `iter_key_prefix`

* return an iterator instead of constructing a vec

* update comments

* additional warning about storage reads

Co-authored-by: default avatarShawn Tabrizi <shawntabrizi@gmail.com>
parent ae3c3045
No related merge requests found
......@@ -61,14 +61,12 @@ pub trait Inspect<AccountId> {
/// Interface for enumerating assets in existence or owned by a given account over a collection
/// of NFTs.
///
/// WARNING: These may be a heavy operations. Do not use when execution time is limited.
pub trait InspectEnumerable<AccountId>: Inspect<AccountId> {
/// Returns the instances of an asset `class` in existence.
fn instances() -> Vec<Self::InstanceId>;
/// Returns an iterator of the instances of an asset `class` in existence.
fn instances() -> Box<dyn Iterator<Item = Self::InstanceId>>;
/// Returns the asset instances of all classes owned by `who`.
fn owned(who: &AccountId) -> Vec<Self::InstanceId>;
/// Returns an iterator of the asset instances of all classes owned by `who`.
fn owned(who: &AccountId) -> Box<dyn Iterator<Item = Self::InstanceId>>;
}
/// Trait for providing an interface for NFT-like assets which may be minted, burned and/or have
......@@ -148,10 +146,10 @@ impl<
A: Get<<F as nonfungibles::Inspect<AccountId>>::ClassId>,
AccountId,
> InspectEnumerable<AccountId> for ItemOf<F, A, AccountId> {
fn instances() -> Vec<Self::InstanceId> {
fn instances() -> Box<dyn Iterator<Item = Self::InstanceId>> {
<F as nonfungibles::InspectEnumerable<AccountId>>::instances(&A::get())
}
fn owned(who: &AccountId) -> Vec<Self::InstanceId> {
fn owned(who: &AccountId) -> Box<dyn Iterator<Item = Self::InstanceId>> {
<F as nonfungibles::InspectEnumerable<AccountId>>::owned_in_class(&A::get(), who)
}
}
......
......@@ -95,20 +95,18 @@ pub trait Inspect<AccountId> {
/// Interface for enumerating assets in existence or owned by a given account over many collections
/// of NFTs.
///
/// WARNING: These may be a heavy operations. Do not use when execution time is limited.
pub trait InspectEnumerable<AccountId>: Inspect<AccountId> {
/// Returns the asset classes in existence.
fn classes() -> Vec<Self::ClassId>;
/// Returns an iterator of the asset classes in existence.
fn classes() -> Box<dyn Iterator<Item = Self::ClassId>>;
/// Returns the instances of an asset `class` in existence.
fn instances(class: &Self::ClassId) -> Vec<Self::InstanceId>;
/// Returns an iterator of the instances of an asset `class` in existence.
fn instances(class: &Self::ClassId) -> Box<dyn Iterator<Item = Self::InstanceId>>;
/// Returns the asset instances of all classes owned by `who`.
fn owned(who: &AccountId) -> Vec<(Self::ClassId, Self::InstanceId)>;
/// Returns an iterator of the asset instances of all classes owned by `who`.
fn owned(who: &AccountId) -> Box<dyn Iterator<Item = (Self::ClassId, Self::InstanceId)>>;
/// Returns the asset instances of `class` owned by `who`.
fn owned_in_class(class: &Self::ClassId, who: &AccountId) -> Vec<Self::InstanceId>;
/// Returns an iterator of the asset instances of `class` owned by `who`.
fn owned_in_class(class: &Self::ClassId, who: &AccountId) -> Box<dyn Iterator<Item = Self::InstanceId>>;
}
/// Trait for providing an interface for multiple classes of NFT-like assets which may be minted,
......
......@@ -19,7 +19,7 @@
use super::*;
use sp_std::convert::TryFrom;
use frame_support::traits::tokens::nonfungibles::{Inspect, Mutate, Transfer};
use frame_support::traits::tokens::nonfungibles::{Inspect, InspectEnumerable, Mutate, Transfer};
use frame_support::BoundedSlice;
use sp_runtime::DispatchResult;
......@@ -106,3 +106,33 @@ impl<T: Config<I>, I: 'static> Transfer<T::AccountId> for Pallet<T, I> {
Self::do_transfer(class.clone(), instance.clone(), destination.clone(), |_, _| Ok(()))
}
}
impl<T: Config<I>, I: 'static> InspectEnumerable<T::AccountId> for Pallet<T, I> {
/// Returns an iterator of the asset classes in existence.
///
/// NOTE: iterating this list invokes a storage read per item.
fn classes() -> Box<dyn Iterator<Item = Self::ClassId>> {
Box::new(ClassMetadataOf::<T, I>::iter_keys())
}
/// Returns an iterator of the instances of an asset `class` in existence.
///
/// NOTE: iterating this list invokes a storage read per item.
fn instances(class: &Self::ClassId) -> Box<dyn Iterator<Item = Self::InstanceId>> {
Box::new(InstanceMetadataOf::<T, I>::iter_key_prefix(class))
}
/// Returns an iterator of the asset instances of all classes owned by `who`.
///
/// NOTE: iterating this list invokes a storage read per item.
fn owned(who: &T::AccountId) -> Box<dyn Iterator<Item = (Self::ClassId, Self::InstanceId)>> {
Box::new(Account::<T, I>::iter_key_prefix((who,)))
}
/// Returns an iterator of the asset instances of `class` owned by `who`.
///
/// NOTE: iterating this list invokes a storage read per item.
fn owned_in_class(class: &Self::ClassId, who: &T::AccountId) -> Box<dyn Iterator<Item = Self::InstanceId>> {
Box::new(Account::<T, I>::iter_key_prefix((who, class)))
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment