--- a/primitives/data-structs/src/bounded.rs
+++ b/primitives/data-structs/src/bounded.rs
@@ -1,3 +1,21 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see .
+
+//! This module contins implementations for support bounded structures in [`serde`].
+
use core::fmt;
use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
use sp_std::vec::Vec;
@@ -7,7 +25,7 @@
storage::{bounded_btree_map::BoundedBTreeMap, bounded_btree_set::BoundedBTreeSet},
};
-/// BoundedVec doesn't supports serde
+/// [`serde`] implementations for [`BoundedVec`].
#[cfg(feature = "serde1")]
pub mod vec_serde {
use core::convert::TryFrom;
@@ -39,6 +57,7 @@
}
}
+/// Format [`BoundedVec`] for debug output.
pub fn vec_debug(v: &BoundedVec, f: &mut fmt::Formatter) -> Result<(), fmt::Error>
where
V: fmt::Debug,
@@ -49,6 +68,7 @@
#[cfg(feature = "serde1")]
#[allow(dead_code)]
+/// [`serde`] implementations for [`BoundedBTreeMap`].
pub mod map_serde {
use core::convert::TryFrom;
use sp_std::collections::btree_map::BTreeMap;
@@ -84,6 +104,7 @@
}
}
+/// Format [`BoundedBTreeMap`] for debug output.
pub fn map_debug(
v: &BoundedBTreeMap,
f: &mut fmt::Formatter,
@@ -98,6 +119,7 @@
#[cfg(feature = "serde1")]
#[allow(dead_code)]
+/// [`serde`] implementations for [`BoundedBTreeSet`].
pub mod set_serde {
use core::convert::TryFrom;
use sp_std::collections::btree_set::BTreeSet;
@@ -129,6 +151,7 @@
}
}
+/// Format [`BoundedBTreeSet`] for debug output.
pub fn set_debug(v: &BoundedBTreeSet, f: &mut fmt::Formatter) -> Result<(), fmt::Error>
where
K: fmt::Debug + Ord,
--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -14,6 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see .
+//! # Primitives crate.
+//!
+//! This crate contains amount of types, traits and constants.
+
#![cfg_attr(not(feature = "std"), no_std)]
use core::{
@@ -82,19 +86,28 @@
} else {
10
};
+
+/// Maximum admins per collection.
pub const COLLECTION_ADMINS_LIMIT: u32 = 5;
+
+/// Maximum tokens per collection.
pub const COLLECTION_TOKEN_LIMIT: u32 = u32::MAX;
+
+/// Maximum tokens per account.
pub const ACCOUNT_TOKEN_OWNERSHIP_LIMIT: u32 = if cfg!(not(feature = "limit-testing")) {
1_000_000
} else {
10
};
-// Timeouts for item types in passed blocks
+/// Default timeout for transfer sponsoring NFT item.
pub const NFT_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;
+/// Default timeout for transfer sponsoring fungible item.
pub const FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;
+/// Default timeout for transfer sponsoring refungible item.
pub const REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT: u32 = 5;
+/// Default timeout for sponsored approving.
pub const SPONSOR_APPROVE_TIMEOUT: u32 = 5;
// Schema limits
@@ -102,23 +115,38 @@
pub const VARIABLE_ON_CHAIN_SCHEMA_LIMIT: u32 = 8192;
pub const CONST_ON_CHAIN_SCHEMA_LIMIT: u32 = 32768;
+// TODO: not used. Delete?
pub const COLLECTION_FIELD_LIMIT: u32 = CONST_ON_CHAIN_SCHEMA_LIMIT;
+/// Maximum length for collection name.
pub const MAX_COLLECTION_NAME_LENGTH: u32 = 64;
+
+/// Maximum length for collection description.
pub const MAX_COLLECTION_DESCRIPTION_LENGTH: u32 = 256;
+
+/// Maximal token prefix length.
pub const MAX_TOKEN_PREFIX_LENGTH: u32 = 16;
+/// Maximal lenght of property key.
pub const MAX_PROPERTY_KEY_LENGTH: u32 = 256;
+
+/// Maximal lenght of property value.
pub const MAX_PROPERTY_VALUE_LENGTH: u32 = 32768;
+
+/// Maximum properties that can be assigned to token.
pub const MAX_PROPERTIES_PER_ITEM: u32 = 64;
+/// Maximal lenght of extended property value.
pub const MAX_AUX_PROPERTY_VALUE_LENGTH: u32 = 2048;
+/// Maximum size for all collection properties.
pub const MAX_COLLECTION_PROPERTIES_SIZE: u32 = 40960;
+
+/// Maximum size for all token properties.
pub const MAX_TOKEN_PROPERTIES_SIZE: u32 = 32768;
/// How much items can be created per single
-/// create_many call
+/// create_many call.
pub const MAX_ITEMS_PER_BATCH: u32 = 200;
/// Used for limit bounded types of token custom data.
@@ -144,7 +172,7 @@
impl EncodeLike for CollectionId {}
impl EncodeLike for u32 {}
-/// Token id
+/// Token id.
#[derive(
Encode,
Decode,
@@ -190,11 +218,17 @@
}
}
+/// Token data.
#[derive(Encode, Decode, Clone, PartialEq, TypeInfo)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub struct TokenData {
+ /// Properties of token.
pub properties: Vec,
+
+ /// Token owner.
pub owner: Option,
+
+ /// Token pieces.
pub pieces: u128,
}
@@ -241,7 +275,7 @@
fn resolve(who: &AccountId, call: &Call) -> Option;
}
-/// Access mode for token.
+/// Access mode for some token operations.
#[derive(Encode, Decode, Eq, Debug, Clone, Copy, PartialEq, TypeInfo, MaxEncodedLen)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub enum AccessMode {
@@ -474,81 +508,129 @@
///
/// Update with `pallet_common::Pallet::clamp_limits`.
// IMPORTANT: When adding/removing fields from this struct - don't forget to also
-// TODO: move `pallet_common::Pallet::clamp_limits() in pallet-common.` into `impl CollectionLimits`.
#[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
+// When adding/removing fields from this struct - don't forget to also update with `pallet_common::Pallet::clamp_limits`.
+// TODO: move `pallet_common::Pallet::clamp_limits` into `impl CollectionLimits`.
+// TODO: may be remove [`Option`] and **pub** from fields and create struct with default values.
pub struct CollectionLimits {
/// How many tokens can a user have on one account.
/// * Default - [`ACCOUNT_TOKEN_OWNERSHIP_LIMIT`].
/// * Limit - [`MAX_TOKEN_OWNERSHIP`].
pub account_token_ownership_limit: Option,
- /// Maximum size of data in bytes of a sponsored transaction.
+ /// How many bytes of data are available for sponsorship.
/// * Default - [`CUSTOM_DATA_LIMIT`].
+ /// * Limit - [`CUSTOM_DATA_LIMIT`].
pub sponsored_data_size: Option,
- /// FIXME should we delete this or repurpose it?
- /// None - setVariableMetadata is not sponsored
- /// Some(v) - setVariableMetadata is sponsored
- /// if there is v block between txs
+ // FIXME should we delete this or repurpose it?
+ /// Times in how many blocks we sponsor data.
+ ///
+ /// If is `Some(v)` then **setVariableMetadata** is sponsored if there is `v` block between transactions.
+ ///
+ /// * Default - [`SponsoringDisabled`](SponsoringRateLimit::SponsoringDisabled).
+ /// * Limit - [`MAX_SPONSOR_TIMEOUT`].
///
/// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
pub sponsored_data_rate_limit: Option,
/// Maximum amount of tokens inside the collection. Chain default: [`COLLECTION_TOKEN_LIMIT`]
+
+ /// How many tokens can be mined into this collection.
+ ///
+ /// * Default - [`COLLECTION_TOKEN_LIMIT`].
+ /// * Limit - [`COLLECTION_TOKEN_LIMIT`].
pub token_limit: Option,
- /// Timeout for sponsoring a token transfer in passed blocks. Chain default:
- /// either [`NFT_SPONSOR_TRANSFER_TIMEOUT`], [`FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT`], or [`REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT`],
- /// depending on the collection type.
+ /// Timeouts for transfer sponsoring.
+ ///
+ /// * Default
+ /// - **Fungible** - [`FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT`]
+ /// - **NFT** - [`NFT_SPONSOR_TRANSFER_TIMEOUT`]
+ /// - **Refungible** - [`REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT`]
+ /// * Limit - [`MAX_SPONSOR_TIMEOUT`].
pub sponsor_transfer_timeout: Option,
- /// Timeout for sponsoring an approval in passed blocks. Chain default: [`SPONSOR_APPROVE_TIMEOUT`]
+
+ /// Timeout for sponsoring an approval in passed blocks.
+ ///
+ /// * Default - [`SPONSOR_APPROVE_TIMEOUT`].
+ /// * Limit - [`MAX_SPONSOR_TIMEOUT`].
pub sponsor_approve_timeout: Option,
- /// Can a token be transferred by the owner. Chain default: `false`
+
+ /// Whether the collection owner of the collection can send tokens (which belong to other users).
+ ///
+ /// * Default - **false**.
pub owner_can_transfer: Option,
- /// Can a token be burned by the owner. Chain default: `true`
+
+ /// Can the collection owner burn other people's tokens.
+ ///
+ /// * Default - **true**.
pub owner_can_destroy: Option,
- /// Can a token be transferred at all. Chain default: `true`
+
+ /// Is it possible to send tokens from this collection between users.
+ ///
+ /// * Default - **true**.
pub transfers_enabled: Option,
}
impl CollectionLimits {
+ /// Get effective value for [`account_token_ownership_limit`](self.account_token_ownership_limit).
pub fn account_token_ownership_limit(&self) -> u32 {
self.account_token_ownership_limit
.unwrap_or(ACCOUNT_TOKEN_OWNERSHIP_LIMIT)
.min(MAX_TOKEN_OWNERSHIP)
}
+
+ /// Get effective value for [`sponsored_data_size`](self.sponsored_data_size).
pub fn sponsored_data_size(&self) -> u32 {
self.sponsored_data_size
.unwrap_or(CUSTOM_DATA_LIMIT)
.min(CUSTOM_DATA_LIMIT)
}
+
+ /// Get effective value for [`token_limit`](self.token_limit).
pub fn token_limit(&self) -> u32 {
self.token_limit
.unwrap_or(COLLECTION_TOKEN_LIMIT)
.min(COLLECTION_TOKEN_LIMIT)
}
+
+ // TODO: may be replace u32 to mode?
+ /// Get effective value for [`sponsor_transfer_timeout`](self.sponsor_transfer_timeout).
pub fn sponsor_transfer_timeout(&self, default: u32) -> u32 {
self.sponsor_transfer_timeout
.unwrap_or(default)
.min(MAX_SPONSOR_TIMEOUT)
}
+
+ /// Get effective value for [`sponsor_approve_timeout`](self.sponsor_approve_timeout).
pub fn sponsor_approve_timeout(&self) -> u32 {
self.sponsor_approve_timeout
.unwrap_or(SPONSOR_APPROVE_TIMEOUT)
.min(MAX_SPONSOR_TIMEOUT)
}
+
+ /// Get effective value for [`owner_can_transfer`](self.owner_can_transfer).
pub fn owner_can_transfer(&self) -> bool {
self.owner_can_transfer.unwrap_or(false)
}
+
+ /// Get effective value for [`owner_can_transfer_instaled`](self.owner_can_transfer_instaled).
pub fn owner_can_transfer_instaled(&self) -> bool {
self.owner_can_transfer.is_some()
}
+
+ /// Get effective value for [`owner_can_destroy`](self.owner_can_destroy).
pub fn owner_can_destroy(&self) -> bool {
self.owner_can_destroy.unwrap_or(true)
}
+
+ /// Get effective value for [`transfers_enabled`](self.transfers_enabled).
pub fn transfers_enabled(&self) -> bool {
self.transfers_enabled.unwrap_or(true)
}
+
+ /// Get effective value for [`sponsored_data_rate_limit`](self.sponsored_data_rate_limit).
pub fn sponsored_data_rate_limit(&self) -> Option {
match self
.sponsored_data_rate_limit
@@ -561,24 +643,46 @@
}
/// Permissions on certain operations within a collection.
-/// All fields are wrapped in `Option`s, where None means chain default.
-// IMPORTANT: When adding/removing fields from this struct - don't forget to also
-// update clamp_limits() in pallet-common.
+///
+/// Some fields are wrapped in [`Option`], where `None` means chain default.
+///
+/// Update with `pallet_common::Pallet::clamp_permissions`.
#[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
+// When adding/removing fields from this struct - don't forget to also update `pallet_common::Pallet::clamp_permissions`.
+// TODO: move `pallet_common::Pallet::clamp_permissions` into `impl CollectionPermissions`.
pub struct CollectionPermissions {
+ /// Access mode.
+ ///
+ /// * Default - [`AccessMode::Normal`].
pub access: Option,
+
+ /// Minting allowance.
+ ///
+ /// * Default - **false**.
pub mint_mode: Option,
+
+ /// Permissions for nesting.
+ ///
+ /// * Default
+ /// - `token_owner` - **false**
+ /// - `collection_admin` - **false**
+ /// - `restricted` - **None**
pub nesting: Option,
}
impl CollectionPermissions {
+ /// Get effective value for [`access`](self.access).
pub fn access(&self) -> AccessMode {
self.access.unwrap_or(AccessMode::Normal)
}
+
+ /// Get effective value for [`mint_mode`](self.mint_mode).
pub fn mint_mode(&self) -> bool {
self.mint_mode.unwrap_or(false)
}
+
+ /// Get effective value for [`nesting`](self.nesting).
pub fn nesting(&self) -> &NestingPermissions {
static DEFAULT: NestingPermissions = NestingPermissions {
token_owner: false,
@@ -591,8 +695,10 @@
}
}
+/// Inner set for collections allowed to nest.
type OwnerRestrictedSetInner = BoundedBTreeSet>;
+/// Wraper for collections set allowing nest.
#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen, Derivative)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
#[derivative(Debug)]
@@ -601,7 +707,9 @@
#[derivative(Debug(format_with = "bounded::set_debug"))]
pub OwnerRestrictedSetInner,
);
+
impl OwnerRestrictedSet {
+ /// Create new set.
pub fn new() -> Self {
Self(Default::default())
}
@@ -623,19 +731,21 @@
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
#[derivative(Debug)]
pub struct NestingPermissions {
- /// Owner of token can nest tokens under it
+ /// Owner of token can nest tokens under it.
pub token_owner: bool,
- /// Admin of token collection can nest tokens under token
+ /// Admin of token collection can nest tokens under token.
pub collection_admin: bool,
- /// If set - only tokens from specified collections can be nested
+ /// If set - only tokens from specified collections can be nested.
pub restricted: Option,
#[cfg(feature = "runtime-benchmarks")]
- /// Anyone can nest tokens, mutually exclusive with `token_owner`, `admin`
+ /// Anyone can nest tokens, mutually exclusive with `token_owner`, `admin`.
pub permissive: bool,
}
/// Enum denominating how often can sponsoring occur if it is enabled.
+///
+/// Used for [`collection limits`](CollectionLimits).
#[derive(Encode, Decode, Debug, Clone, Copy, PartialEq, TypeInfo, MaxEncodedLen)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub enum SponsoringRateLimit {
@@ -653,6 +763,7 @@
/// Key-value pairs used to describe the token as metadata
#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
#[derivative(Debug(format_with = "bounded::vec_debug"))]
+ /// Properties that wil be assignet to created item.
pub properties: CollectionPropertiesVec,
}
@@ -674,7 +785,7 @@
#[derivative(Debug(format_with = "bounded::vec_debug"))]
pub const_data: BoundedVec,
- /// Number of pieces the RFT is split into
+ /// Pieces of created token.
pub pieces: u128,
/// Key-value pairs used to describe the token as metadata
@@ -683,6 +794,7 @@
pub properties: CollectionPropertiesVec,
}
+// TODO: remove this.
#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub enum MetaUpdatePermission {
@@ -692,57 +804,75 @@
}
/// Enum holding data used for creation of all three item types.
+/// Unified data for create item.
#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub enum CreateItemData {
+ /// Data for create NFT.
NFT(CreateNftData),
+ /// Data for create Fungible item.
Fungible(CreateFungibleData),
+ /// Data for create ReFungible item.
ReFungible(CreateReFungibleData),
}
-/// Explicit NFT creation data with meta parameters.
+/// Extended data for create NFT.
#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]
#[derivative(Debug)]
pub struct CreateNftExData {
+ /// Properties that wil be assignet to created item.
#[derivative(Debug(format_with = "bounded::vec_debug"))]
pub properties: CollectionPropertiesVec,
+
+ /// Owner of creating item.
pub owner: CrossAccountId,
}
-/// Explicit RFT creation data with meta parameters.
+/// Extended data for create ReFungible item.
#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]
#[derivative(Debug(bound = "CrossAccountId: fmt::Debug + Ord"))]
pub struct CreateRefungibleExData {
+ /// Custom data stored in token.
#[derivative(Debug(format_with = "bounded::vec_debug"))]
pub const_data: BoundedVec,
+
+ /// Users who will be assigned the specified number of token parts.
#[derivative(Debug(format_with = "bounded::map_debug"))]
pub users: BoundedBTreeMap>,
#[derivative(Debug(format_with = "bounded::vec_debug"))]
pub properties: CollectionPropertiesVec,
}
-/// Explicit item creation data with meta parameters, namely the owner.
+/// Unified extended data for creating item.
#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, TypeInfo, Derivative)]
#[derivative(Debug(bound = "CrossAccountId: fmt::Debug + Ord"))]
pub enum CreateItemExData {
+ /// Extended data for create NFT.
NFT(
#[derivative(Debug(format_with = "bounded::vec_debug"))]
BoundedVec, ConstU32>,
),
+
+ /// Extended data for create Fungible item.
Fungible(
#[derivative(Debug(format_with = "bounded::map_debug"))]
BoundedBTreeMap>,
),
- /// Many tokens, each may have only one owner
+
+ /// Extended data for create ReFungible item in case of
+ /// many tokens, each may have only one owner
RefungibleMultipleItems(
#[derivative(Debug(format_with = "bounded::vec_debug"))]
BoundedVec, ConstU32>,
),
- /// Single token, which may have many owners
+
+ /// Extended data for create ReFungible item in case of
+ /// single token, which may have many owners
RefungibleMultipleOwners(CreateRefungibleExData),
}
impl CreateItemData {
+ /// Get size of custom data.
pub fn data_size(&self) -> usize {
match self {
CreateItemData::ReFungible(data) => data.const_data.len(),
@@ -774,18 +904,28 @@
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
// todo possibly rename to be used generally as an address pair
pub struct TokenChild {
+ /// Token id.
pub token: TokenId,
+
+ /// Collection id.
pub collection: CollectionId,
}
+/// Collection statistics.
#[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub struct CollectionStats {
+ /// Number of created items.
pub created: u32,
+
+ /// Number of burned items.
pub destroyed: u32,
+
+ /// Number of current items.
pub alive: u32,
}
+/// This type works like [`PhantomData`] but supports generating _scale-info_ descriptions to generate node metadata.
#[derive(Encode, Decode, Clone, Debug)]
#[cfg_attr(feature = "std", derive(PartialEq))]
pub struct PhantomType(core::marker::PhantomData);
@@ -811,22 +951,36 @@
}
}
+/// Bounded vector of bytes.
pub type BoundedBytes = BoundedVec;
+/// Extra properties for external collections.
pub type AuxPropertyValue = BoundedBytes>;
+/// Property key.
pub type PropertyKey = BoundedBytes>;
+
+/// Property value.
pub type PropertyValue = BoundedBytes>;
+/// Property permission.
#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub struct PropertyPermission {
+ /// Permission to change the property and property permission.
+ ///
+ /// If it **false** then you can not change corresponding property even if [`collection_admin`] and [`token_owner`] are **true**.
pub mutable: bool,
+
+ /// Change permission for the collection administrator.
pub collection_admin: bool,
+
+ /// Permission to change the property for the owner of the token.
pub token_owner: bool,
}
impl PropertyPermission {
+ /// Creates mutable property permission but changes restricted for collection admin and token owner.
pub fn none() -> Self {
Self {
mutable: true,
@@ -836,12 +990,15 @@
}
}
+/// Property is simpl key-value record.
#[derive(Encode, Decode, Debug, TypeInfo, Clone, PartialEq, MaxEncodedLen)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub struct Property {
+ /// Property key.
#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
pub key: PropertyKey,
+ /// Property value.
#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
pub value: PropertyValue,
}
@@ -852,12 +1009,15 @@
}
}
+/// Record for proprty key permission.
#[derive(Encode, Decode, TypeInfo, Debug, MaxEncodedLen, PartialEq, Clone)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub struct PropertyKeyPermission {
+ /// Key.
#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
pub key: PropertyKey,
+ /// Permission.
pub permission: PropertyPermission,
}
@@ -867,15 +1027,35 @@
}
}
+/// Errors for properties actions.
#[derive(Debug)]
pub enum PropertiesError {
+ /// The space allocated for properties has run out.
+ ///
+ /// * Limit for colection - [`MAX_COLLECTION_PROPERTIES_SIZE`].
+ /// * Limit for token - [`MAX_TOKEN_PROPERTIES_SIZE`].
NoSpaceForProperty,
+
+ /// The property limit has been reached.
+ ///
+ /// * Limit - [`MAX_PROPERTIES_PER_ITEM`].
PropertyLimitReached,
+
+ /// Property key contains not allowed character.
InvalidCharacterInPropertyKey,
+
+ /// Property key length is too long.
+ ///
+ /// * Limit - [`MAX_PROPERTY_KEY_LENGTH`].
PropertyKeyIsTooLong,
+
+ /// Property key is empty.
EmptyPropertyKey,
}
+/// Marker for scope of property.
+///
+/// Scoped property can't be changed by user. Used for external collections.
#[derive(Encode, Decode, MaxEncodedLen, TypeInfo, PartialEq, Clone, Copy)]
pub enum PropertyScope {
None,
@@ -883,6 +1063,7 @@
}
impl PropertyScope {
+ /// Apply scope to property key.
pub fn apply(self, key: PropertyKey) -> Result {
let scope_str: &[u8] = match self {
Self::None => return Ok(key),
@@ -896,16 +1077,20 @@
}
}
+/// Trait for operate with properties.
pub trait TrySetProperty: Sized {
type Value;
+ /// Try to set property with scope.
fn try_scoped_set(
&mut self,
scope: PropertyScope,
key: PropertyKey,
value: Self::Value,
) -> Result<(), PropertiesError>;
-
+
+
+ /// Try to set property with scope from iterator.
fn try_scoped_set_from_iter(
&mut self,
scope: PropertyScope,
@@ -923,10 +1108,12 @@
Ok(())
}
+ /// Try to set property.
fn try_set(&mut self, key: PropertyKey, value: Self::Value) -> Result<(), PropertiesError> {
self.try_scoped_set(PropertyScope::None, key, value)
}
-
+
+ /// Try to set property from iterator.
fn try_set_from_iter(&mut self, iter: I) -> Result<(), PropertiesError>
where
I: Iterator,
@@ -936,6 +1123,7 @@
}
}
+/// Wrapped map for storing properties.
#[derive(Encode, Decode, TypeInfo, Derivative, Clone, PartialEq, MaxEncodedLen)]
#[derivative(Default(bound = ""))]
pub struct PropertiesMap(
@@ -943,24 +1131,29 @@
);
impl PropertiesMap {
+ /// Create new property map.
pub fn new() -> Self {
Self(BoundedBTreeMap::new())
}
+ /// Remove property from map.
pub fn remove(&mut self, key: &PropertyKey) -> Result