12345678910111213141516171819use super::*;20use up_data_structs::PropertyScope;21use core::convert::AsRef;222324pub const RESOURCE_ID_PREFIX: &str = "rsid-";2526pub const USER_PROPERTY_PREFIX: &str = "userprop-";272829pub const RMRK_SCOPE: PropertyScope = PropertyScope::Rmrk;303132pub enum RmrkProperty<'r> {33 Metadata,34 CollectionType,35 RmrkInternalCollectionId,36 TokenType,37 Transferable,38 RoyaltyInfo,39 Equipped,40 ResourcePriorities,41 NextResourceId,42 ResourceId(RmrkResourceId),43 PendingNftAccept,44 PendingChildren,45 AssociatedBases,46 Parts,47 Base,48 Src,49 EquippedNft,50 BaseType,51 ExternalPartId,52 EquippableList,53 ZIndex,54 ThemeName,55 ThemeInherit,56 UserProperty(&'r [u8]),57}5859impl<'r> RmrkProperty<'r> {60 61 pub fn to_key<T: Config>(self) -> Result<PropertyKey, Error<T>> {62 fn get_bytes<T: AsRef<[u8]>>(container: &T) -> &[u8] {63 container.as_ref()64 }6566 macro_rules! key {67 ($($component:expr),+) => {68 PropertyKey::try_from([$(key!(@ &$component)),+].concat())69 .map_err(|_| <Error<T>>::RmrkPropertyKeyIsTooLong)70 };7172 (@ $key:expr) => {73 get_bytes($key)74 };75 }7677 match self {78 Self::Metadata => key!("metadata"),79 Self::CollectionType => key!("collection-type"),80 Self::RmrkInternalCollectionId => key!("internal-id"),81 Self::TokenType => key!("token-type"),82 Self::Transferable => key!("transferable"),83 Self::RoyaltyInfo => key!("royalty-info"),84 Self::Equipped => key!("equipped"),85 Self::ResourcePriorities => key!("resource-priorities"),86 Self::NextResourceId => key!("next-resource-id"),87 Self::ResourceId(id) => key!(RESOURCE_ID_PREFIX, id.to_le_bytes()),88 Self::PendingNftAccept => key!("pending-nft-accept"),89 Self::PendingChildren => key!("pending-children"),90 Self::AssociatedBases => key!("assoc-bases"),91 Self::Parts => key!("parts"),92 Self::Base => key!("base"),93 Self::Src => key!("src"),94 Self::EquippedNft => key!("equipped-nft"),95 Self::BaseType => key!("base-type"),96 Self::ExternalPartId => key!("ext-part-id"),97 Self::EquippableList => key!("equippable-list"),98 Self::ZIndex => key!("z-index"),99 Self::ThemeName => key!("theme-name"),100 Self::ThemeInherit => key!("theme-inherit"),101 Self::UserProperty(name) => key!(USER_PROPERTY_PREFIX, name),102 }103 }104}105106107pub fn strip_key_prefix(key: &PropertyKey, prefix: &str) -> Option<PropertyKey> {108 let key_prefix = PropertyKey::try_from(prefix.as_bytes().to_vec()).ok()?;109 let key_prefix = RMRK_SCOPE.apply(key_prefix).ok()?;110111 key.as_slice()112 .strip_prefix(key_prefix.as_slice())?113 .to_vec()114 .try_into()115 .ok()116}117118119pub fn is_valid_key_prefix(key: &PropertyKey, prefix: &str) -> bool {120 strip_key_prefix(key, prefix).is_some()121}