git.delta.rocks / unique-network / refs/commits / 8c0746583b47

difftreelog

refactor(up-nft) optional serde support

Yaroslav Bolyukin2021-08-09parent: #b5bd6c7.patch.diff
in: master

2 files changed

modifiedprimitives/nft/Cargo.tomldiffbeforeafterboth
--- a/primitives/nft/Cargo.toml
+++ b/primitives/nft/Cargo.toml
@@ -10,7 +10,7 @@
 
 [dependencies]
 codec = { package = "parity-scale-codec", version = "2.2.0", default-features = false, features = ['derive'] }
-serde = { version = "1.0.119", features = ['derive'], default-features = false }
+serde = { version = "1.0.119", features = ['derive'], default-features = false, optional = true }
 max-encoded-len = { default-features = false, features = ['derive'], version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
 frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
 frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
@@ -22,6 +22,7 @@
 [features]
 default = ["std"]
 std = [
+  "serde1",
   "serde/std",
   "codec/std",
   "max-encoded-len/std",
@@ -30,4 +31,5 @@
   "sp-runtime/std",
   "sp-core/std",
   "sp-std/std",
-]
\ No newline at end of file
+]
+serde1 = ["serde"]
\ No newline at end of file
modifiedprimitives/nft/src/lib.rsdiffbeforeafterboth
before · primitives/nft/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23pub use serde::{Serialize, Deserialize};45use sp_runtime::sp_std::prelude::Vec;6use codec::{Decode, Encode};7use max_encoded_len::MaxEncodedLen;8pub use frame_support::{9	BoundedVec, construct_runtime, decl_event, decl_module, decl_storage, decl_error,10	dispatch::DispatchResult,11	ensure, fail, parameter_types,12	traits::{13		Currency, ExistenceRequirement, Get, Imbalance, KeyOwnerProofSystem, OnUnbalanced,14		Randomness, IsSubType, WithdrawReasons,15	},16	weights::{17		constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},18		DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,19		WeightToFeePolynomial, DispatchClass,20	},21	StorageValue, transactional,22};23use derivative::Derivative;2425pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;26pub const MAX_REFUNGIBLE_PIECES: u128 = 1_000_000_000_000_000_000_000;27pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;28pub const MAX_TOKEN_OWNERSHIP: u32 = 10_000_000;2930// TODO: Somehow use ChainLimits for BoundedVec len calculation?31// Do we need ChainLimits anyway, if we can change them via forkless upgrades?32parameter_types! {33pub const MaxDataSize: u32 = 2048;34// TODO: This limit isn't checked for substrate create_multiple_items call35pub const MaxItemsPerBatch: u32 = 200;36}3738pub type CollectionId = u32;39pub type TokenId = u32;40pub type DecimalPoints = u8;4142#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, Serialize, Deserialize)]43pub enum CollectionMode {44	Invalid,45	NFT,46	// decimal points47	Fungible(DecimalPoints),48	ReFungible,49}5051impl Default for CollectionMode {52	fn default() -> Self {53		Self::Invalid54	}55}5657impl CollectionMode {58	pub fn id(&self) -> u8 {59		match self {60			CollectionMode::Invalid => 0,61			CollectionMode::NFT => 1,62			CollectionMode::Fungible(_) => 2,63			CollectionMode::ReFungible => 3,64		}65	}66}6768pub trait SponsoringResolve<AccountId, Call> {69	fn resolve(who: &AccountId, call: &Call) -> Option<AccountId>;70}7172#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, Serialize, Deserialize)]73pub enum AccessMode {74	Normal,75	WhiteList,76}77impl Default for AccessMode {78	fn default() -> Self {79		Self::Normal80	}81}8283#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq, Serialize, Deserialize)]84pub enum SchemaVersion {85	ImageURL,86	Unique,87}88impl Default for SchemaVersion {89	fn default() -> Self {90		Self::ImageURL91	}92}9394#[derive(Encode, Decode, Default, Debug, Clone, PartialEq, Serialize, Deserialize)]95pub struct Ownership<AccountId> {96	pub owner: AccountId,97	pub fraction: u128,98}99100#[derive(Encode, Decode, Debug, Clone, PartialEq, Serialize, Deserialize)]101pub enum SponsorshipState<AccountId> {102	/// The fees are applied to the transaction sender103	Disabled,104	Unconfirmed(AccountId),105	/// Transactions are sponsored by specified account106	Confirmed(AccountId),107}108109impl<AccountId> SponsorshipState<AccountId> {110	pub fn sponsor(&self) -> Option<&AccountId> {111		match self {112			Self::Confirmed(sponsor) => Some(sponsor),113			_ => None,114		}115	}116117	pub fn pending_sponsor(&self) -> Option<&AccountId> {118		match self {119			Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor),120			_ => None,121		}122	}123124	pub fn confirmed(&self) -> bool {125		matches!(self, Self::Confirmed(_))126	}127}128129impl<T> Default for SponsorshipState<T> {130	fn default() -> Self {131		Self::Disabled132	}133}134135#[derive(Encode, Decode, Clone, PartialEq)]136#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]137pub struct Collection<T: frame_system::Config> {138	pub owner: T::AccountId,139	pub mode: CollectionMode,140	pub access: AccessMode,141	pub decimal_points: DecimalPoints,142	pub name: Vec<u16>,        // 64 include null escape char143	pub description: Vec<u16>, // 256 include null escape char144	pub token_prefix: Vec<u8>, // 16 include null escape char145	pub mint_mode: bool,146	pub offchain_schema: Vec<u8>,147	pub schema_version: SchemaVersion,148	pub sponsorship: SponsorshipState<T::AccountId>,149	pub limits: CollectionLimits<T::BlockNumber>, // Collection private restrictions150	pub variable_on_chain_schema: Vec<u8>,        //151	pub const_on_chain_schema: Vec<u8>,           //152	pub transfers_enabled: bool,153}154155#[derive(Encode, Decode, Debug, Clone, PartialEq, Serialize, Deserialize)]156pub struct NftItemType<AccountId> {157	pub owner: AccountId,158	pub const_data: Vec<u8>,159	pub variable_data: Vec<u8>,160}161162#[derive(Encode, Decode, Default, Debug, Clone, PartialEq, Serialize, Deserialize)]163pub struct FungibleItemType {164	pub value: u128,165}166167#[derive(Encode, Decode, Debug, Clone, PartialEq, Serialize, Deserialize)]168pub struct ReFungibleItemType<AccountId> {169	pub owner: Vec<Ownership<AccountId>>,170	pub const_data: Vec<u8>,171	pub variable_data: Vec<u8>,172}173174#[derive(Encode, Decode, Debug, Clone, PartialEq, Serialize, Deserialize)]175pub struct CollectionLimits<BlockNumber: Encode + Decode> {176	pub account_token_ownership_limit: u32,177	pub sponsored_data_size: u32,178	/// None - setVariableMetadata is not sponsored179	/// Some(v) - setVariableMetadata is sponsored180	///           if there is v block between txs181	pub sponsored_data_rate_limit: Option<BlockNumber>,182	pub token_limit: u32,183184	// Timeouts for item types in passed blocks185	pub sponsor_transfer_timeout: u32,186	pub owner_can_transfer: bool,187	pub owner_can_destroy: bool,188}189190impl<BlockNumber: Encode + Decode> Default for CollectionLimits<BlockNumber> {191	fn default() -> Self {192		Self {193			account_token_ownership_limit: 10_000_000,194			token_limit: u32::max_value(),195			sponsored_data_size: u32::MAX,196			sponsored_data_rate_limit: None,197			sponsor_transfer_timeout: 14400,198			owner_can_transfer: true,199			owner_can_destroy: true,200		}201	}202}203204#[derive(Encode, Decode, Default, Debug, Clone, PartialEq, Serialize, Deserialize)]205pub struct ChainLimits {206	pub collection_numbers_limit: u32,207	pub account_token_ownership_limit: u32,208	pub collections_admins_limit: u64,209	pub custom_data_limit: u32,210211	// Timeouts for item types in passed blocks212	pub nft_sponsor_transfer_timeout: u32,213	pub fungible_sponsor_transfer_timeout: u32,214	pub refungible_sponsor_transfer_timeout: u32,215216	// Schema limits217	pub offchain_schema_limit: u32,218	pub variable_on_chain_schema_limit: u32,219	pub const_on_chain_schema_limit: u32,220}221222/// BoundedVec doesn't supports serde223mod bounded_serde {224	use core::convert::TryFrom;225	use frame_support::{BoundedVec, traits::Get};226	use serde::{227		ser::{self, Serialize},228		de::{self, Deserialize, Error},229	};230	use sp_std::vec::Vec;231232	pub fn serialize<D, V, S>(value: &BoundedVec<V, S>, serializer: D) -> Result<D::Ok, D::Error>233	where234		D: ser::Serializer,235		V: Serialize,236	{237		let vec: &Vec<_> = &value;238		vec.serialize(serializer)239	}240241	pub fn deserialize<'de, D, V, S>(deserializer: D) -> Result<BoundedVec<V, S>, D::Error>242	where243		D: de::Deserializer<'de>,244		V: de::Deserialize<'de>,245		S: Get<u32>,246	{247		// TODO: Implement custom visitor, which will limit vec size at parse time? Will serde only be used by chainspec?248		let vec = <Vec<V>>::deserialize(deserializer)?;249		let len = vec.len();250		TryFrom::try_from(vec).map_err(|_| D::Error::invalid_length(len, &"lesser size"))251	}252}253254#[derive(255	Encode, Decode, MaxEncodedLen, Default, Derivative, Clone, PartialEq, Serialize, Deserialize,256)]257#[derivative(Debug)]258pub struct CreateNftData {259	#[serde(with = "bounded_serde")]260	#[derivative(Debug = "ignore")]261	pub const_data: BoundedVec<u8, MaxDataSize>,262	#[serde(with = "bounded_serde")]263	#[derivative(Debug = "ignore")]264	pub variable_data: BoundedVec<u8, MaxDataSize>,265}266267#[derive(268	Encode, Decode, MaxEncodedLen, Default, Debug, Clone, PartialEq, Serialize, Deserialize,269)]270pub struct CreateFungibleData {271	pub value: u128,272}273274#[derive(275	Encode, Decode, MaxEncodedLen, Default, Derivative, Clone, PartialEq, Serialize, Deserialize,276)]277#[derivative(Debug)]278pub struct CreateReFungibleData {279	#[serde(with = "bounded_serde")]280	#[derivative(Debug = "ignore")]281	pub const_data: BoundedVec<u8, MaxDataSize>,282	#[serde(with = "bounded_serde")]283	#[derivative(Debug = "ignore")]284	pub variable_data: BoundedVec<u8, MaxDataSize>,285	pub pieces: u128,286}287288#[derive(Encode, Decode, MaxEncodedLen, Debug, Clone, PartialEq, Serialize, Deserialize)]289pub enum CreateItemData {290	NFT(CreateNftData),291	Fungible(CreateFungibleData),292	ReFungible(CreateReFungibleData),293}294295impl CreateItemData {296	pub fn data_size(&self) -> usize {297		match self {298			CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),299			CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),300			_ => 0,301		}302	}303}304305impl From<CreateNftData> for CreateItemData {306	fn from(item: CreateNftData) -> Self {307		CreateItemData::NFT(item)308	}309}310311impl From<CreateReFungibleData> for CreateItemData {312	fn from(item: CreateReFungibleData) -> Self {313		CreateItemData::ReFungible(item)314	}315}316317impl From<CreateFungibleData> for CreateItemData {318	fn from(item: CreateFungibleData) -> Self {319		CreateItemData::Fungible(item)320	}321}
after · primitives/nft/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23#[cfg(feature = "serde")]4pub use serde::{Serialize, Deserialize};56use sp_runtime::sp_std::prelude::Vec;7use codec::{Decode, Encode};8use max_encoded_len::MaxEncodedLen;9pub use frame_support::{10	BoundedVec, construct_runtime, decl_event, decl_module, decl_storage, decl_error,11	dispatch::DispatchResult,12	ensure, fail, parameter_types,13	traits::{14		Currency, ExistenceRequirement, Get, Imbalance, KeyOwnerProofSystem, OnUnbalanced,15		Randomness, IsSubType, WithdrawReasons,16	},17	weights::{18		constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},19		DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,20		WeightToFeePolynomial, DispatchClass,21	},22	StorageValue, transactional,23};24use derivative::Derivative;2526pub const MAX_DECIMAL_POINTS: DecimalPoints = 30;27pub const MAX_REFUNGIBLE_PIECES: u128 = 1_000_000_000_000_000_000_000;28pub const MAX_SPONSOR_TIMEOUT: u32 = 10_368_000;29pub const MAX_TOKEN_OWNERSHIP: u32 = 10_000_000;3031// TODO: Somehow use ChainLimits for BoundedVec len calculation?32// Do we need ChainLimits anyway, if we can change them via forkless upgrades?33parameter_types! {34pub const MaxDataSize: u32 = 2048;35// TODO: This limit isn't checked for substrate create_multiple_items call36pub const MaxItemsPerBatch: u32 = 200;37}3839pub type CollectionId = u32;40pub type TokenId = u32;41pub type DecimalPoints = u8;4243#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]44#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]45pub enum CollectionMode {46	Invalid,47	NFT,48	// decimal points49	Fungible(DecimalPoints),50	ReFungible,51}5253impl Default for CollectionMode {54	fn default() -> Self {55		Self::Invalid56	}57}5859impl CollectionMode {60	pub fn id(&self) -> u8 {61		match self {62			CollectionMode::Invalid => 0,63			CollectionMode::NFT => 1,64			CollectionMode::Fungible(_) => 2,65			CollectionMode::ReFungible => 3,66		}67	}68}6970pub trait SponsoringResolve<AccountId, Call> {71	fn resolve(who: &AccountId, call: &Call) -> Option<AccountId>;72}7374#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]75#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]76pub enum AccessMode {77	Normal,78	WhiteList,79}80impl Default for AccessMode {81	fn default() -> Self {82		Self::Normal83	}84}8586#[derive(Encode, Decode, Eq, Debug, Clone, PartialEq)]87#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]88pub enum SchemaVersion {89	ImageURL,90	Unique,91}92impl Default for SchemaVersion {93	fn default() -> Self {94		Self::ImageURL95	}96}9798#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]99#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]100pub struct Ownership<AccountId> {101	pub owner: AccountId,102	pub fraction: u128,103}104105#[derive(Encode, Decode, Debug, Clone, PartialEq)]106#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]107pub enum SponsorshipState<AccountId> {108	/// The fees are applied to the transaction sender109	Disabled,110	Unconfirmed(AccountId),111	/// Transactions are sponsored by specified account112	Confirmed(AccountId),113}114115impl<AccountId> SponsorshipState<AccountId> {116	pub fn sponsor(&self) -> Option<&AccountId> {117		match self {118			Self::Confirmed(sponsor) => Some(sponsor),119			_ => None,120		}121	}122123	pub fn pending_sponsor(&self) -> Option<&AccountId> {124		match self {125			Self::Unconfirmed(sponsor) | Self::Confirmed(sponsor) => Some(sponsor),126			_ => None,127		}128	}129130	pub fn confirmed(&self) -> bool {131		matches!(self, Self::Confirmed(_))132	}133}134135impl<T> Default for SponsorshipState<T> {136	fn default() -> Self {137		Self::Disabled138	}139}140141#[derive(Encode, Decode, Clone, PartialEq)]142#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]143pub struct Collection<T: frame_system::Config> {144	pub owner: T::AccountId,145	pub mode: CollectionMode,146	pub access: AccessMode,147	pub decimal_points: DecimalPoints,148	pub name: Vec<u16>,        // 64 include null escape char149	pub description: Vec<u16>, // 256 include null escape char150	pub token_prefix: Vec<u8>, // 16 include null escape char151	pub mint_mode: bool,152	pub offchain_schema: Vec<u8>,153	pub schema_version: SchemaVersion,154	pub sponsorship: SponsorshipState<T::AccountId>,155	pub limits: CollectionLimits<T::BlockNumber>, // Collection private restrictions156	pub variable_on_chain_schema: Vec<u8>,        //157	pub const_on_chain_schema: Vec<u8>,           //158	pub transfers_enabled: bool,159}160161#[derive(Encode, Decode, Debug, Clone, PartialEq)]162#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]163pub struct NftItemType<AccountId> {164	pub owner: AccountId,165	pub const_data: Vec<u8>,166	pub variable_data: Vec<u8>,167}168169#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]170#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]171pub struct FungibleItemType {172	pub value: u128,173}174175#[derive(Encode, Decode, Debug, Clone, PartialEq)]176#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]177pub struct ReFungibleItemType<AccountId> {178	pub owner: Vec<Ownership<AccountId>>,179	pub const_data: Vec<u8>,180	pub variable_data: Vec<u8>,181}182183#[derive(Encode, Decode, Debug, Clone, PartialEq)]184#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]185pub struct CollectionLimits<BlockNumber: Encode + Decode> {186	pub account_token_ownership_limit: u32,187	pub sponsored_data_size: u32,188	/// None - setVariableMetadata is not sponsored189	/// Some(v) - setVariableMetadata is sponsored190	///           if there is v block between txs191	pub sponsored_data_rate_limit: Option<BlockNumber>,192	pub token_limit: u32,193194	// Timeouts for item types in passed blocks195	pub sponsor_transfer_timeout: u32,196	pub owner_can_transfer: bool,197	pub owner_can_destroy: bool,198}199200impl<BlockNumber: Encode + Decode> Default for CollectionLimits<BlockNumber> {201	fn default() -> Self {202		Self {203			account_token_ownership_limit: 10_000_000,204			token_limit: u32::max_value(),205			sponsored_data_size: u32::MAX,206			sponsored_data_rate_limit: None,207			sponsor_transfer_timeout: 14400,208			owner_can_transfer: true,209			owner_can_destroy: true,210		}211	}212}213214#[derive(Encode, Decode, Default, Debug, Clone, PartialEq)]215#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]216pub struct ChainLimits {217	pub collection_numbers_limit: u32,218	pub account_token_ownership_limit: u32,219	pub collections_admins_limit: u64,220	pub custom_data_limit: u32,221222	// Timeouts for item types in passed blocks223	pub nft_sponsor_transfer_timeout: u32,224	pub fungible_sponsor_transfer_timeout: u32,225	pub refungible_sponsor_transfer_timeout: u32,226227	// Schema limits228	pub offchain_schema_limit: u32,229	pub variable_on_chain_schema_limit: u32,230	pub const_on_chain_schema_limit: u32,231}232233/// BoundedVec doesn't supports serde234#[cfg(feature = "serde1")]235mod bounded_serde {236	use core::convert::TryFrom;237	use frame_support::{BoundedVec, traits::Get};238	use serde::{239		ser::{self, Serialize},240		de::{self, Deserialize, Error},241	};242	use sp_std::vec::Vec;243244	pub fn serialize<D, V, S>(value: &BoundedVec<V, S>, serializer: D) -> Result<D::Ok, D::Error>245	where246		D: ser::Serializer,247		V: Serialize,248	{249		let vec: &Vec<_> = &value;250		vec.serialize(serializer)251	}252253	pub fn deserialize<'de, D, V, S>(deserializer: D) -> Result<BoundedVec<V, S>, D::Error>254	where255		D: de::Deserializer<'de>,256		V: de::Deserialize<'de>,257		S: Get<u32>,258	{259		// TODO: Implement custom visitor, which will limit vec size at parse time? Will serde only be used by chainspec?260		let vec = <Vec<V>>::deserialize(deserializer)?;261		let len = vec.len();262		TryFrom::try_from(vec).map_err(|_| D::Error::invalid_length(len, &"lesser size"))263	}264}265266#[derive(Encode, Decode, MaxEncodedLen, Default, Derivative, Clone, PartialEq)]267#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]268#[derivative(Debug)]269pub struct CreateNftData {270	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]271	#[derivative(Debug = "ignore")]272	pub const_data: BoundedVec<u8, MaxDataSize>,273	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]274	#[derivative(Debug = "ignore")]275	pub variable_data: BoundedVec<u8, MaxDataSize>,276}277278#[derive(Encode, Decode, MaxEncodedLen, Default, Debug, Clone, PartialEq)]279#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]280pub struct CreateFungibleData {281	pub value: u128,282}283284#[derive(Encode, Decode, MaxEncodedLen, Default, Derivative, Clone, PartialEq)]285#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]286#[derivative(Debug)]287pub struct CreateReFungibleData {288	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]289	#[derivative(Debug = "ignore")]290	pub const_data: BoundedVec<u8, MaxDataSize>,291	#[cfg_attr(feature = "serde1", serde(with = "bounded_serde"))]292	#[derivative(Debug = "ignore")]293	pub variable_data: BoundedVec<u8, MaxDataSize>,294	pub pieces: u128,295}296297#[derive(Encode, Decode, MaxEncodedLen, Debug, Clone, PartialEq)]298#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]299pub enum CreateItemData {300	NFT(CreateNftData),301	Fungible(CreateFungibleData),302	ReFungible(CreateReFungibleData),303}304305impl CreateItemData {306	pub fn data_size(&self) -> usize {307		match self {308			CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),309			CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),310			_ => 0,311		}312	}313}314315impl From<CreateNftData> for CreateItemData {316	fn from(item: CreateNftData) -> Self {317		CreateItemData::NFT(item)318	}319}320321impl From<CreateReFungibleData> for CreateItemData {322	fn from(item: CreateReFungibleData) -> Self {323		CreateItemData::ReFungible(item)324	}325}326327impl From<CreateFungibleData> for CreateItemData {328	fn from(item: CreateFungibleData) -> Self {329		CreateItemData::Fungible(item)330	}331}