Skip to content
asset.rs 30.4 KiB
Newer Older
Francisco Aguirre's avatar
Francisco Aguirre committed
// Copyright (C) Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Substrate 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.

// Substrate 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 Polkadot.  If not, see <http://www.gnu.org/licenses/>.

//! Cross-Consensus Message format asset data structures.
//!
//! This encompasses four types for representing assets:
//! - `Asset`: A description of a single asset, either an instance of a non-fungible or some amount
//!   of a fungible.
//! - `Assets`: A collection of `Asset`s. These are stored in a `Vec` and sorted with fungibles
//!   first.
//! - `Wild`: A single asset wildcard, this can either be "all" assets, or all assets of a specific
//!   kind.
//! - `AssetFilter`: A combination of `Wild` and `Assets` designed for efficiently filtering an XCM
//!   holding account.

use super::{InteriorLocation, Location, Reanchorable};
use crate::v3::{
	AssetId as OldAssetId, AssetInstance as OldAssetInstance, Fungibility as OldFungibility,
	MultiAsset as OldAsset, MultiAssetFilter as OldAssetFilter, MultiAssets as OldAssets,
	WildFungibility as OldWildFungibility, WildMultiAsset as OldWildAsset,
};
use alloc::{vec, vec::Vec};
use bounded_collections::{BoundedVec, ConstU32};
Francisco Aguirre's avatar
Francisco Aguirre committed
use core::{
	cmp::Ordering,
	convert::{TryFrom, TryInto},
};
use parity_scale_codec::{self as codec, Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;

/// A general identifier for an instance of a non-fungible asset class.
#[derive(
	Copy,
	Clone,
	Eq,
	PartialEq,
	Ord,
	PartialOrd,
	Encode,
	Decode,
	Debug,
	TypeInfo,
	MaxEncodedLen,
	serde::Serialize,
	serde::Deserialize,
Francisco Aguirre's avatar
Francisco Aguirre committed
)]
pub enum AssetInstance {
	/// Undefined - used if the non-fungible asset class has only one instance.
	Undefined,

	/// A compact index. Technically this could be greater than `u128`, but this implementation
	/// supports only values up to `2**128 - 1`.
	Index(#[codec(compact)] u128),

	/// A 4-byte fixed-length datum.
	Array4([u8; 4]),

	/// An 8-byte fixed-length datum.
	Array8([u8; 8]),

	/// A 16-byte fixed-length datum.
	Array16([u8; 16]),

	/// A 32-byte fixed-length datum.
	Array32([u8; 32]),
}

impl TryFrom<OldAssetInstance> for AssetInstance {
	type Error = ();
	fn try_from(value: OldAssetInstance) -> Result<Self, Self::Error> {
		use OldAssetInstance::*;
		Ok(match value {
			Undefined => Self::Undefined,
			Index(n) => Self::Index(n),
			Array4(n) => Self::Array4(n),
			Array8(n) => Self::Array8(n),
			Array16(n) => Self::Array16(n),
			Array32(n) => Self::Array32(n),
		})
	}
}

impl From<()> for AssetInstance {
	fn from(_: ()) -> Self {
		Self::Undefined
	}
}

impl From<[u8; 4]> for AssetInstance {
	fn from(x: [u8; 4]) -> Self {
		Self::Array4(x)
	}
}

impl From<[u8; 8]> for AssetInstance {
	fn from(x: [u8; 8]) -> Self {
		Self::Array8(x)
	}
}

impl From<[u8; 16]> for AssetInstance {
	fn from(x: [u8; 16]) -> Self {
		Self::Array16(x)
	}
}

impl From<[u8; 32]> for AssetInstance {
	fn from(x: [u8; 32]) -> Self {
		Self::Array32(x)
	}
}

impl From<u8> for AssetInstance {
	fn from(x: u8) -> Self {
		Self::Index(x as u128)
	}
}

impl From<u16> for AssetInstance {
	fn from(x: u16) -> Self {
		Self::Index(x as u128)
	}
}

impl From<u32> for AssetInstance {
	fn from(x: u32) -> Self {
		Self::Index(x as u128)
	}
}

impl From<u64> for AssetInstance {
	fn from(x: u64) -> Self {
		Self::Index(x as u128)
	}
}

impl TryFrom<AssetInstance> for () {
	type Error = ();
	fn try_from(x: AssetInstance) -> Result<Self, ()> {
		match x {
			AssetInstance::Undefined => Ok(()),
			_ => Err(()),
		}
	}
}

impl TryFrom<AssetInstance> for [u8; 4] {
	type Error = ();
	fn try_from(x: AssetInstance) -> Result<Self, ()> {
		match x {
			AssetInstance::Array4(x) => Ok(x),
			_ => Err(()),
		}
	}
}

impl TryFrom<AssetInstance> for [u8; 8] {
	type Error = ();
	fn try_from(x: AssetInstance) -> Result<Self, ()> {
		match x {
			AssetInstance::Array8(x) => Ok(x),
			_ => Err(()),
		}
	}
}

impl TryFrom<AssetInstance> for [u8; 16] {
	type Error = ();
	fn try_from(x: AssetInstance) -> Result<Self, ()> {
		match x {
			AssetInstance::Array16(x) => Ok(x),
			_ => Err(()),
		}
	}
}

impl TryFrom<AssetInstance> for [u8; 32] {
	type Error = ();
	fn try_from(x: AssetInstance) -> Result<Self, ()> {
		match x {
			AssetInstance::Array32(x) => Ok(x),
			_ => Err(()),
		}
	}
}

impl TryFrom<AssetInstance> for u8 {
Loading full blame...