frame_support/traits/tokens/
nonfungible_v2.rs1use super::nonfungibles_v2 as nonfungibles;
28use crate::{
29 dispatch::{DispatchResult, Parameter},
30 traits::Get,
31};
32use alloc::vec::Vec;
33use codec::{Decode, Encode};
34use sp_runtime::TokenError;
35
36pub trait Inspect<AccountId> {
38 type ItemId: Parameter;
40
41 fn owner(item: &Self::ItemId) -> Option<AccountId>;
44
45 fn attribute(_item: &Self::ItemId, _key: &[u8]) -> Option<Vec<u8>> {
49 None
50 }
51
52 fn custom_attribute(
56 _account: &AccountId,
57 _item: &Self::ItemId,
58 _key: &[u8],
59 ) -> Option<Vec<u8>> {
60 None
61 }
62
63 fn system_attribute(_item: &Self::ItemId, _key: &[u8]) -> Option<Vec<u8>> {
67 None
68 }
69
70 fn typed_attribute<K: Encode, V: Decode>(item: &Self::ItemId, key: &K) -> Option<V> {
74 key.using_encoded(|d| Self::attribute(item, d))
75 .and_then(|v| V::decode(&mut &v[..]).ok())
76 }
77
78 fn typed_custom_attribute<K: Encode, V: Decode>(
82 account: &AccountId,
83 item: &Self::ItemId,
84 key: &K,
85 ) -> Option<V> {
86 key.using_encoded(|d| Self::custom_attribute(account, item, d))
87 .and_then(|v| V::decode(&mut &v[..]).ok())
88 }
89
90 fn typed_system_attribute<K: Encode, V: Decode>(item: &Self::ItemId, key: &K) -> Option<V> {
94 key.using_encoded(|d| Self::system_attribute(item, d))
95 .and_then(|v| V::decode(&mut &v[..]).ok())
96 }
97
98 fn can_transfer(_item: &Self::ItemId) -> bool {
102 true
103 }
104}
105
106pub trait InspectEnumerable<AccountId>: Inspect<AccountId> {
109 type ItemsIterator: Iterator<Item = Self::ItemId>;
111 type OwnedIterator: Iterator<Item = Self::ItemId>;
113
114 fn items() -> Self::ItemsIterator;
116
117 fn owned(who: &AccountId) -> Self::OwnedIterator;
119}
120
121pub trait Mutate<AccountId, ItemConfig>: Inspect<AccountId> {
124 fn mint_into(
128 _item: &Self::ItemId,
129 _who: &AccountId,
130 _config: &ItemConfig,
131 _deposit_collection_owner: bool,
132 ) -> DispatchResult {
133 Err(TokenError::Unsupported.into())
134 }
135
136 fn burn(_item: &Self::ItemId, _maybe_check_owner: Option<&AccountId>) -> DispatchResult {
140 Err(TokenError::Unsupported.into())
141 }
142
143 fn set_attribute(_item: &Self::ItemId, _key: &[u8], _value: &[u8]) -> DispatchResult {
147 Err(TokenError::Unsupported.into())
148 }
149
150 fn set_typed_attribute<K: Encode, V: Encode>(
154 item: &Self::ItemId,
155 key: &K,
156 value: &V,
157 ) -> DispatchResult {
158 key.using_encoded(|k| value.using_encoded(|v| Self::set_attribute(item, k, v)))
159 }
160
161 fn set_metadata(_who: &AccountId, _item: &Self::ItemId, _data: &[u8]) -> DispatchResult {
165 Err(TokenError::Unsupported.into())
166 }
167
168 fn clear_attribute(_item: &Self::ItemId, _key: &[u8]) -> DispatchResult {
172 Err(TokenError::Unsupported.into())
173 }
174
175 fn clear_typed_attribute<K: Encode>(item: &Self::ItemId, key: &K) -> DispatchResult {
179 key.using_encoded(|k| Self::clear_attribute(item, k))
180 }
181
182 fn clear_metadata(_who: &AccountId, _item: &Self::ItemId) -> DispatchResult {
186 Err(TokenError::Unsupported.into())
187 }
188}
189
190pub trait Transfer<AccountId>: Inspect<AccountId> {
192 fn transfer(item: &Self::ItemId, destination: &AccountId) -> DispatchResult;
194 fn disable_transfer(item: &Self::ItemId) -> DispatchResult;
198 fn enable_transfer(item: &Self::ItemId) -> DispatchResult;
202}
203
204pub struct ItemOf<
207 F: nonfungibles::Inspect<AccountId>,
208 A: Get<<F as nonfungibles::Inspect<AccountId>>::CollectionId>,
209 AccountId,
210>(core::marker::PhantomData<(F, A, AccountId)>);
211
212impl<
213 F: nonfungibles::Inspect<AccountId>,
214 A: Get<<F as nonfungibles::Inspect<AccountId>>::CollectionId>,
215 AccountId,
216 > Inspect<AccountId> for ItemOf<F, A, AccountId>
217{
218 type ItemId = <F as nonfungibles::Inspect<AccountId>>::ItemId;
219 fn owner(item: &Self::ItemId) -> Option<AccountId> {
220 <F as nonfungibles::Inspect<AccountId>>::owner(&A::get(), item)
221 }
222 fn attribute(item: &Self::ItemId, key: &[u8]) -> Option<Vec<u8>> {
223 <F as nonfungibles::Inspect<AccountId>>::attribute(&A::get(), item, key)
224 }
225 fn custom_attribute(account: &AccountId, item: &Self::ItemId, key: &[u8]) -> Option<Vec<u8>> {
226 <F as nonfungibles::Inspect<AccountId>>::custom_attribute(account, &A::get(), item, key)
227 }
228 fn system_attribute(item: &Self::ItemId, key: &[u8]) -> Option<Vec<u8>> {
229 <F as nonfungibles::Inspect<AccountId>>::system_attribute(&A::get(), Some(item), key)
230 }
231 fn typed_attribute<K: Encode, V: Decode>(item: &Self::ItemId, key: &K) -> Option<V> {
232 <F as nonfungibles::Inspect<AccountId>>::typed_attribute(&A::get(), item, key)
233 }
234 fn typed_custom_attribute<K: Encode, V: Decode>(
235 account: &AccountId,
236 item: &Self::ItemId,
237 key: &K,
238 ) -> Option<V> {
239 <F as nonfungibles::Inspect<AccountId>>::typed_custom_attribute(
240 account,
241 &A::get(),
242 item,
243 key,
244 )
245 }
246 fn typed_system_attribute<K: Encode, V: Decode>(item: &Self::ItemId, key: &K) -> Option<V> {
247 <F as nonfungibles::Inspect<AccountId>>::typed_system_attribute(&A::get(), Some(item), key)
248 }
249 fn can_transfer(item: &Self::ItemId) -> bool {
250 <F as nonfungibles::Inspect<AccountId>>::can_transfer(&A::get(), item)
251 }
252}
253
254impl<
255 F: nonfungibles::InspectEnumerable<AccountId>,
256 A: Get<<F as nonfungibles::Inspect<AccountId>>::CollectionId>,
257 AccountId,
258 > InspectEnumerable<AccountId> for ItemOf<F, A, AccountId>
259{
260 type ItemsIterator = <F as nonfungibles::InspectEnumerable<AccountId>>::ItemsIterator;
261 type OwnedIterator =
262 <F as nonfungibles::InspectEnumerable<AccountId>>::OwnedInCollectionIterator;
263
264 fn items() -> Self::ItemsIterator {
265 <F as nonfungibles::InspectEnumerable<AccountId>>::items(&A::get())
266 }
267 fn owned(who: &AccountId) -> Self::OwnedIterator {
268 <F as nonfungibles::InspectEnumerable<AccountId>>::owned_in_collection(&A::get(), who)
269 }
270}
271
272impl<
273 F: nonfungibles::Mutate<AccountId, ItemConfig>,
274 A: Get<<F as nonfungibles::Inspect<AccountId>>::CollectionId>,
275 AccountId,
276 ItemConfig,
277 > Mutate<AccountId, ItemConfig> for ItemOf<F, A, AccountId>
278{
279 fn mint_into(
280 item: &Self::ItemId,
281 who: &AccountId,
282 config: &ItemConfig,
283 deposit_collection_owner: bool,
284 ) -> DispatchResult {
285 <F as nonfungibles::Mutate<AccountId, ItemConfig>>::mint_into(
286 &A::get(),
287 item,
288 who,
289 config,
290 deposit_collection_owner,
291 )
292 }
293 fn burn(item: &Self::ItemId, maybe_check_owner: Option<&AccountId>) -> DispatchResult {
294 <F as nonfungibles::Mutate<AccountId, ItemConfig>>::burn(&A::get(), item, maybe_check_owner)
295 }
296 fn set_attribute(item: &Self::ItemId, key: &[u8], value: &[u8]) -> DispatchResult {
297 <F as nonfungibles::Mutate<AccountId, ItemConfig>>::set_attribute(
298 &A::get(),
299 item,
300 key,
301 value,
302 )
303 }
304 fn set_typed_attribute<K: Encode, V: Encode>(
305 item: &Self::ItemId,
306 key: &K,
307 value: &V,
308 ) -> DispatchResult {
309 <F as nonfungibles::Mutate<AccountId, ItemConfig>>::set_typed_attribute(
310 &A::get(),
311 item,
312 key,
313 value,
314 )
315 }
316 fn clear_attribute(item: &Self::ItemId, key: &[u8]) -> DispatchResult {
317 <F as nonfungibles::Mutate<AccountId, ItemConfig>>::clear_attribute(&A::get(), item, key)
318 }
319 fn clear_typed_attribute<K: Encode>(item: &Self::ItemId, key: &K) -> DispatchResult {
320 <F as nonfungibles::Mutate<AccountId, ItemConfig>>::clear_typed_attribute(
321 &A::get(),
322 item,
323 key,
324 )
325 }
326}
327
328impl<
329 F: nonfungibles::Transfer<AccountId>,
330 A: Get<<F as nonfungibles::Inspect<AccountId>>::CollectionId>,
331 AccountId,
332 > Transfer<AccountId> for ItemOf<F, A, AccountId>
333{
334 fn transfer(item: &Self::ItemId, destination: &AccountId) -> DispatchResult {
335 <F as nonfungibles::Transfer<AccountId>>::transfer(&A::get(), item, destination)
336 }
337 fn disable_transfer(item: &Self::ItemId) -> DispatchResult {
338 <F as nonfungibles::Transfer<AccountId>>::disable_transfer(&A::get(), item)
339 }
340 fn enable_transfer(item: &Self::ItemId) -> DispatchResult {
341 <F as nonfungibles::Transfer<AccountId>>::enable_transfer(&A::get(), item)
342 }
343}