near_contract_standards/non_fungible_token/enumeration/
enumeration_impl.rsuse super::NonFungibleTokenEnumeration;
use crate::non_fungible_token::token::Token;
use crate::non_fungible_token::NonFungibleToken;
use near_sdk::json_types::U128;
use near_sdk::{env, require, AccountId};
type TokenId = String;
impl NonFungibleToken {
fn enum_get_token(&self, owner_id: AccountId, token_id: TokenId) -> Token {
let metadata = self.token_metadata_by_id.as_ref().and_then(|m| m.get(&token_id));
let approved_account_ids = self
.approvals_by_id
.as_ref()
.map(|approvals_by_id| approvals_by_id.get(&token_id.to_string()).unwrap_or_default());
Token { token_id, owner_id, metadata, approved_account_ids }
}
}
impl NonFungibleTokenEnumeration for NonFungibleToken {
fn nft_total_supply(&self) -> U128 {
(self.owner_by_id.len() as u128).into()
}
fn nft_tokens(&self, from_index: Option<U128>, limit: Option<u64>) -> Vec<Token> {
let start_index: u128 = from_index.map(From::from).unwrap_or_default();
require!(
(self.owner_by_id.len() as u128) >= start_index,
"Out of bounds, please use a smaller from_index."
);
let limit = limit.map(|v| v as usize).unwrap_or(usize::MAX);
require!(limit != 0, "Cannot provide limit of 0.");
self.owner_by_id
.iter()
.skip(start_index as usize)
.take(limit)
.map(|(token_id, owner_id)| self.enum_get_token(owner_id, token_id))
.collect()
}
fn nft_supply_for_owner(&self, account_id: AccountId) -> U128 {
let tokens_per_owner = self.tokens_per_owner.as_ref().unwrap_or_else(|| {
env::panic_str(
"Could not find tokens_per_owner when calling a method on the \
enumeration standard.",
)
});
tokens_per_owner
.get(&account_id)
.map(|account_tokens| U128::from(account_tokens.len() as u128))
.unwrap_or(U128(0))
}
fn nft_tokens_for_owner(
&self,
account_id: AccountId,
from_index: Option<U128>,
limit: Option<u64>,
) -> Vec<Token> {
let tokens_per_owner = self.tokens_per_owner.as_ref().unwrap_or_else(|| {
env::panic_str(
"Could not find tokens_per_owner when calling a method on the \
enumeration standard.",
)
});
let token_set = if let Some(token_set) = tokens_per_owner.get(&account_id) {
token_set
} else {
return vec![];
};
if token_set.is_empty() {
return vec![];
}
let limit = limit.map(|v| v as usize).unwrap_or(usize::MAX);
require!(limit != 0, "Cannot provide limit of 0.");
let start_index: u128 = from_index.map(From::from).unwrap_or_default();
require!(
token_set.len() as u128 > start_index,
"Out of bounds, please use a smaller from_index."
);
token_set
.iter()
.skip(start_index as usize)
.take(limit)
.map(|token_id| self.enum_get_token(account_id.clone(), token_id))
.collect()
}
}