Skip to main content

ics721_types/
token_types.rs

1use std::ops::Deref;
2
3use cosmwasm_schema::cw_serde;
4use cosmwasm_std::{Binary, StdResult};
5use cw_storage_plus::{Bound, Bounder, Key, KeyDeserialize, Prefixer, PrimaryKey};
6
7/// A token ID according to the ICS-721 spec. The newtype pattern is
8/// used here to provide some distinction between token and class IDs
9/// in the type system.
10#[cw_serde]
11pub struct TokenId(String);
12
13/// A token according to the ICS-721 spec.
14#[cw_serde]
15pub struct Token {
16    /// A unique identifier for the token.
17    pub id: TokenId,
18    /// Optional URI pointing to off-chain metadata about the token.
19    pub uri: Option<String>,
20    /// Optional base64 encoded metadata about the token.
21    pub data: Option<Binary>,
22}
23
24/// A class ID according to the ICS-721 spec. The newtype pattern is
25/// used here to provide some distinction between token and class IDs
26/// in the type system.
27#[cw_serde]
28pub struct ClassId(String);
29
30#[cw_serde]
31pub struct Class {
32    /// A unique (from the source chain's perspective) identifier for
33    /// the class.
34    pub id: ClassId,
35    /// Optional URI pointing to off-chain metadata about the class.
36    pub uri: Option<String>,
37    /// Optional base64 encoded metadata about the class.
38    pub data: Option<Binary>,
39}
40
41impl TokenId {
42    pub fn new<T>(token_id: T) -> Self
43    where
44        T: Into<String>,
45    {
46        Self(token_id.into())
47    }
48}
49
50impl ClassId {
51    pub fn new<T>(class_id: T) -> Self
52    where
53        T: Into<String>,
54    {
55        Self(class_id.into())
56    }
57}
58
59#[cw_serde]
60pub struct ClassToken {
61    pub class_id: ClassId,
62    pub token_id: TokenId,
63}
64
65impl<'a> Bounder<'a> for ClassId {
66    fn inclusive_bound(self) -> Option<cw_storage_plus::Bound<'a, Self>> {
67        Some(Bound::inclusive(self))
68    }
69
70    fn exclusive_bound(self) -> Option<cw_storage_plus::Bound<'a, Self>> {
71        Some(Bound::exclusive(self))
72    }
73}
74
75// Allow ClassId to be inferred into String
76impl From<ClassId> for String {
77    fn from(c: ClassId) -> Self {
78        c.0
79    }
80}
81
82impl From<TokenId> for String {
83    fn from(t: TokenId) -> Self {
84        t.0
85    }
86}
87
88impl Deref for ClassId {
89    type Target = str;
90
91    fn deref(&self) -> &Self::Target {
92        &self.0
93    }
94}
95
96impl std::fmt::Display for ClassId {
97    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98        write!(f, "{}", self.0)
99    }
100}
101
102// Allow ClassId to be inferred into Key - using String.key()
103impl<'a> PrimaryKey<'a> for ClassId {
104    type Prefix = <String as PrimaryKey<'a>>::Prefix;
105    type SubPrefix = <String as PrimaryKey<'a>>::SubPrefix;
106    type Suffix = <String as PrimaryKey<'a>>::Suffix;
107    type SuperSuffix = <String as PrimaryKey<'a>>::SuperSuffix;
108
109    fn key(&self) -> Vec<cw_storage_plus::Key> {
110        self.0.key()
111    }
112}
113
114impl<'a> PrimaryKey<'a> for TokenId {
115    type Prefix = <String as PrimaryKey<'a>>::Prefix;
116    type SubPrefix = <String as PrimaryKey<'a>>::SubPrefix;
117    type Suffix = <String as PrimaryKey<'a>>::Suffix;
118    type SuperSuffix = <String as PrimaryKey<'a>>::SuperSuffix;
119
120    fn key(&self) -> Vec<cw_storage_plus::Key> {
121        self.0.key()
122    }
123}
124
125impl<'a> Prefixer<'a> for ClassId {
126    fn prefix(&self) -> Vec<Key> {
127        self.0.prefix()
128    }
129}
130
131impl<'a> Prefixer<'a> for TokenId {
132    fn prefix(&self) -> Vec<Key> {
133        self.0.prefix()
134    }
135}
136
137impl KeyDeserialize for ClassId {
138    type Output = <String as KeyDeserialize>::Output;
139    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
140        String::from_vec(value)
141    }
142}
143
144impl KeyDeserialize for TokenId {
145    type Output = <String as KeyDeserialize>::Output;
146    fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
147        String::from_vec(value)
148    }
149}