1use crate::{traits::Contains, TypeInfo};
21use alloc::{vec, vec::Vec};
22use codec::{Decode, DecodeWithMemTracking, Encode, FullCodec, HasCompact, MaxEncodedLen};
23use core::fmt::Debug;
24use sp_arithmetic::traits::{AtLeast32BitUnsigned, Zero};
25use sp_core::RuntimeDebug;
26use sp_runtime::{
27 traits::{Convert, MaybeSerializeDeserialize},
28 ArithmeticError, DispatchError, TokenError,
29};
30
31#[derive(Copy, Clone, RuntimeDebug, Eq, PartialEq)]
33pub enum Provenance {
34 Minted,
37 Extant,
39}
40
41#[derive(Copy, Clone, RuntimeDebug, Eq, PartialEq)]
43pub enum Restriction {
44 Free,
46 OnHold,
48}
49
50#[derive(Copy, Clone, RuntimeDebug, Eq, PartialEq)]
52pub enum Preservation {
53 Expendable,
55 Protect,
57 Preserve,
60}
61
62#[derive(Copy, Clone, RuntimeDebug, Eq, PartialEq)]
64pub enum Fortitude {
65 Polite,
67 Force,
70}
71
72#[derive(Copy, Clone, RuntimeDebug, Eq, PartialEq)]
75pub enum Precision {
76 Exact,
79 BestEffort,
82}
83
84#[derive(Copy, Clone, RuntimeDebug, Eq, PartialEq)]
86pub enum WithdrawConsequence<Balance> {
87 BalanceLow,
90 WouldDie,
93 UnknownAsset,
96 Underflow,
99 Overflow,
102 Frozen,
104 ReducedToZero(Balance),
107 Success,
109}
110
111impl<Balance: Zero> WithdrawConsequence<Balance> {
112 pub fn into_result(self, keep_nonzero: bool) -> Result<Balance, DispatchError> {
115 use WithdrawConsequence::*;
116 match self {
117 BalanceLow => Err(TokenError::FundsUnavailable.into()),
118 WouldDie => Err(TokenError::OnlyProvider.into()),
119 UnknownAsset => Err(TokenError::UnknownAsset.into()),
120 Underflow => Err(ArithmeticError::Underflow.into()),
121 Overflow => Err(ArithmeticError::Overflow.into()),
122 Frozen => Err(TokenError::Frozen.into()),
123 ReducedToZero(_) if keep_nonzero => Err(TokenError::NotExpendable.into()),
124 ReducedToZero(result) => Ok(result),
125 Success => Ok(Zero::zero()),
126 }
127 }
128}
129
130#[derive(Copy, Clone, RuntimeDebug, Eq, PartialEq)]
132pub enum DepositConsequence {
133 BelowMinimum,
137 CannotCreate,
140 UnknownAsset,
143 Overflow,
147 Success,
149 Blocked,
151}
152
153impl DepositConsequence {
154 pub fn into_result(self) -> Result<(), DispatchError> {
156 use DepositConsequence::*;
157 Err(match self {
158 BelowMinimum => TokenError::BelowMinimum.into(),
159 CannotCreate => TokenError::CannotCreate.into(),
160 UnknownAsset => TokenError::UnknownAsset.into(),
161 Overflow => ArithmeticError::Overflow.into(),
162 Blocked => TokenError::Blocked.into(),
163 Success => return Ok(()),
164 })
165 }
166}
167
168#[derive(Copy, Clone, RuntimeDebug, Eq, PartialEq)]
170pub enum ExistenceRequirement {
171 KeepAlive,
176 AllowDeath,
178}
179
180#[derive(
182 PartialEq,
183 Eq,
184 Clone,
185 Copy,
186 Encode,
187 Decode,
188 DecodeWithMemTracking,
189 RuntimeDebug,
190 scale_info::TypeInfo,
191 MaxEncodedLen,
192)]
193pub enum BalanceStatus {
194 Free,
196 Reserved,
198}
199
200bitflags::bitflags! {
201 #[derive(Encode, Decode, MaxEncodedLen)]
203 pub struct WithdrawReasons: u8 {
204 const TRANSACTION_PAYMENT = 0b00000001;
206 const TRANSFER = 0b00000010;
208 const RESERVE = 0b00000100;
210 const FEE = 0b00001000;
212 const TIP = 0b00010000;
214 }
215}
216
217impl WithdrawReasons {
218 pub fn except(one: WithdrawReasons) -> WithdrawReasons {
230 let mut flags = Self::all();
231 flags.toggle(one);
232 flags
233 }
234}
235
236pub trait AssetId:
238 FullCodec
239 + DecodeWithMemTracking
240 + Clone
241 + Eq
242 + PartialEq
243 + Debug
244 + scale_info::TypeInfo
245 + MaxEncodedLen
246{
247}
248impl<
249 T: FullCodec
250 + DecodeWithMemTracking
251 + Clone
252 + Eq
253 + PartialEq
254 + Debug
255 + scale_info::TypeInfo
256 + MaxEncodedLen,
257 > AssetId for T
258{
259}
260
261pub trait Balance:
263 AtLeast32BitUnsigned
264 + FullCodec
265 + DecodeWithMemTracking
266 + HasCompact<Type: DecodeWithMemTracking>
267 + Copy
268 + Default
269 + Debug
270 + scale_info::TypeInfo
271 + MaxEncodedLen
272 + Send
273 + Sync
274 + MaybeSerializeDeserialize
275 + 'static
276{
277}
278impl<
279 T: AtLeast32BitUnsigned
280 + FullCodec
281 + DecodeWithMemTracking
282 + HasCompact<Type: DecodeWithMemTracking>
283 + Copy
284 + Default
285 + Debug
286 + scale_info::TypeInfo
287 + MaxEncodedLen
288 + Send
289 + Sync
290 + MaybeSerializeDeserialize
291 + 'static,
292 > Balance for T
293{
294}
295
296pub trait ConversionToAssetBalance<InBalance, AssetId, AssetBalance> {
298 type Error;
299 fn to_asset_balance(balance: InBalance, asset_id: AssetId)
300 -> Result<AssetBalance, Self::Error>;
301}
302
303pub trait ConversionFromAssetBalance<AssetBalance, AssetId, OutBalance> {
305 type Error;
306 fn from_asset_balance(
307 balance: AssetBalance,
308 asset_id: AssetId,
309 ) -> Result<OutBalance, Self::Error>;
310 #[cfg(feature = "runtime-benchmarks")]
313 fn ensure_successful(asset_id: AssetId);
314}
315
316pub struct UnityAssetBalanceConversion;
319impl<AssetBalance, AssetId, OutBalance>
320 ConversionFromAssetBalance<AssetBalance, AssetId, OutBalance> for UnityAssetBalanceConversion
321where
322 AssetBalance: Into<OutBalance>,
323{
324 type Error = ();
325 fn from_asset_balance(balance: AssetBalance, _: AssetId) -> Result<OutBalance, Self::Error> {
326 Ok(balance.into())
327 }
328 #[cfg(feature = "runtime-benchmarks")]
329 fn ensure_successful(_: AssetId) {}
330}
331impl<InBalance, AssetId, AssetBalance> ConversionToAssetBalance<InBalance, AssetId, AssetBalance>
332 for UnityAssetBalanceConversion
333where
334 InBalance: Into<AssetBalance>,
335{
336 type Error = ();
337 fn to_asset_balance(balance: InBalance, _: AssetId) -> Result<AssetBalance, Self::Error> {
338 Ok(balance.into())
339 }
340}
341
342pub struct UnityOrOuterConversion<C, O>(core::marker::PhantomData<(C, O)>);
346impl<AssetBalance, AssetId, OutBalance, C, O>
347 ConversionFromAssetBalance<AssetBalance, AssetId, OutBalance> for UnityOrOuterConversion<C, O>
348where
349 C: Contains<AssetId>,
350 O: ConversionFromAssetBalance<AssetBalance, AssetId, OutBalance>,
351 AssetBalance: Into<OutBalance>,
352{
353 type Error = O::Error;
354 fn from_asset_balance(
355 balance: AssetBalance,
356 asset_id: AssetId,
357 ) -> Result<OutBalance, Self::Error> {
358 if C::contains(&asset_id) {
359 return Ok(balance.into());
360 }
361 O::from_asset_balance(balance, asset_id)
362 }
363 #[cfg(feature = "runtime-benchmarks")]
364 fn ensure_successful(asset_id: AssetId) {
365 O::ensure_successful(asset_id)
366 }
367}
368impl<InBalance, AssetId, AssetBalance, C, O>
369 ConversionToAssetBalance<InBalance, AssetId, AssetBalance> for UnityOrOuterConversion<C, O>
370where
371 C: Contains<AssetId>,
372 O: ConversionToAssetBalance<InBalance, AssetId, AssetBalance>,
373 InBalance: Into<AssetBalance>,
374{
375 type Error = O::Error;
376 fn to_asset_balance(
377 balance: InBalance,
378 asset_id: AssetId,
379 ) -> Result<AssetBalance, Self::Error> {
380 if C::contains(&asset_id) {
381 return Ok(balance.into());
382 }
383 O::to_asset_balance(balance, asset_id)
384 }
385}
386
387pub trait ProvideAssetReserves<A, R> {
389 fn reserves(id: &A) -> Vec<R>;
390}
391impl<A, R> ProvideAssetReserves<A, R> for () {
392 fn reserves(_id: &A) -> Vec<R> {
393 vec![]
394 }
395}
396
397pub trait Locker<CollectionId, ItemId> {
400 fn is_locked(collection: CollectionId, item: ItemId) -> bool;
402}
403
404impl<CollectionId, ItemId> Locker<CollectionId, ItemId> for () {
405 fn is_locked(_collection: CollectionId, _item: ItemId) -> bool {
409 false
410 }
411}
412
413pub trait GetSalary<Rank, AccountId, Balance> {
415 fn get_salary(rank: Rank, who: &AccountId) -> Balance;
418}
419
420pub struct ConvertRank<C>(core::marker::PhantomData<C>);
422impl<A, R, B, C: Convert<R, B>> GetSalary<R, A, B> for ConvertRank<C> {
423 fn get_salary(rank: R, _: &A) -> B {
424 C::convert(rank)
425 }
426}
427
428#[derive(
430 Encode,
431 Decode,
432 DecodeWithMemTracking,
433 Clone,
434 PartialEq,
435 Eq,
436 RuntimeDebug,
437 MaxEncodedLen,
438 TypeInfo,
439)]
440pub struct IdAmount<Id, Balance> {
441 pub id: Id,
443 pub amount: Balance,
445}