use crate::{traits::Contains, TypeInfo};
use alloc::{vec, vec::Vec};
use codec::{Decode, DecodeWithMemTracking, Encode, FullCodec, HasCompact, MaxEncodedLen};
use core::fmt::Debug;
use sp_arithmetic::traits::{AtLeast32BitUnsigned, Zero};
use sp_runtime::{
traits::{Convert, MaybeSerializeDeserialize},
ArithmeticError, DispatchError, TokenError,
};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Provenance {
Minted,
Extant,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Restriction {
Free,
OnHold,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Preservation {
Expendable,
Protect,
Preserve,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Fortitude {
Polite,
Force,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Precision {
Exact,
BestEffort,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum WithdrawConsequence<Balance> {
BalanceLow,
WouldDie,
UnknownAsset,
Underflow,
Overflow,
Frozen,
ReducedToZero(Balance),
Success,
}
impl<Balance: Zero> WithdrawConsequence<Balance> {
pub fn into_result(self, keep_nonzero: bool) -> Result<Balance, DispatchError> {
use WithdrawConsequence::*;
match self {
BalanceLow => Err(TokenError::FundsUnavailable.into()),
WouldDie => Err(TokenError::OnlyProvider.into()),
UnknownAsset => Err(TokenError::UnknownAsset.into()),
Underflow => Err(ArithmeticError::Underflow.into()),
Overflow => Err(ArithmeticError::Overflow.into()),
Frozen => Err(TokenError::Frozen.into()),
ReducedToZero(_) if keep_nonzero => Err(TokenError::NotExpendable.into()),
ReducedToZero(result) => Ok(result),
Success => Ok(Zero::zero()),
}
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum DepositConsequence {
BelowMinimum,
CannotCreate,
UnknownAsset,
Overflow,
Success,
Blocked,
}
impl DepositConsequence {
pub fn into_result(self) -> Result<(), DispatchError> {
use DepositConsequence::*;
Err(match self {
BelowMinimum => TokenError::BelowMinimum.into(),
CannotCreate => TokenError::CannotCreate.into(),
UnknownAsset => TokenError::UnknownAsset.into(),
Overflow => ArithmeticError::Overflow.into(),
Blocked => TokenError::Blocked.into(),
Success => return Ok(()),
})
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ExistenceRequirement {
KeepAlive,
AllowDeath,
}
#[derive(
PartialEq,
Eq,
Clone,
Copy,
Encode,
Decode,
DecodeWithMemTracking,
Debug,
scale_info::TypeInfo,
MaxEncodedLen,
)]
pub enum BalanceStatus {
Free,
Reserved,
}
bitflags::bitflags! {
#[derive(Encode, Decode, MaxEncodedLen)]
pub struct WithdrawReasons: u8 {
const TRANSACTION_PAYMENT = 0b00000001;
const TRANSFER = 0b00000010;
const RESERVE = 0b00000100;
const FEE = 0b00001000;
const TIP = 0b00010000;
}
}
impl WithdrawReasons {
pub fn except(one: WithdrawReasons) -> WithdrawReasons {
let mut flags = Self::all();
flags.toggle(one);
flags
}
}
pub trait AssetId:
FullCodec
+ DecodeWithMemTracking
+ Clone
+ Eq
+ PartialEq
+ Debug
+ scale_info::TypeInfo
+ MaxEncodedLen
{
}
impl<
T: FullCodec
+ DecodeWithMemTracking
+ Clone
+ Eq
+ PartialEq
+ Debug
+ scale_info::TypeInfo
+ MaxEncodedLen,
> AssetId for T
{
}
pub trait Balance:
AtLeast32BitUnsigned
+ FullCodec
+ DecodeWithMemTracking
+ HasCompact<Type: DecodeWithMemTracking>
+ Copy
+ Default
+ Debug
+ scale_info::TypeInfo
+ MaxEncodedLen
+ Send
+ Sync
+ MaybeSerializeDeserialize
+ 'static
{
}
impl<
T: AtLeast32BitUnsigned
+ FullCodec
+ DecodeWithMemTracking
+ HasCompact<Type: DecodeWithMemTracking>
+ Copy
+ Default
+ Debug
+ scale_info::TypeInfo
+ MaxEncodedLen
+ Send
+ Sync
+ MaybeSerializeDeserialize
+ 'static,
> Balance for T
{
}
pub trait ConversionToAssetBalance<InBalance, AssetId, AssetBalance> {
type Error;
fn to_asset_balance(balance: InBalance, asset_id: AssetId)
-> Result<AssetBalance, Self::Error>;
}
pub trait ConversionFromAssetBalance<AssetBalance, AssetId, OutBalance> {
type Error;
fn from_asset_balance(
balance: AssetBalance,
asset_id: AssetId,
) -> Result<OutBalance, Self::Error>;
#[cfg(feature = "runtime-benchmarks")]
fn ensure_successful(asset_id: AssetId);
}
pub struct UnityAssetBalanceConversion;
impl<AssetBalance, AssetId, OutBalance>
ConversionFromAssetBalance<AssetBalance, AssetId, OutBalance> for UnityAssetBalanceConversion
where
AssetBalance: Into<OutBalance>,
{
type Error = ();
fn from_asset_balance(balance: AssetBalance, _: AssetId) -> Result<OutBalance, Self::Error> {
Ok(balance.into())
}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_successful(_: AssetId) {}
}
impl<InBalance, AssetId, AssetBalance> ConversionToAssetBalance<InBalance, AssetId, AssetBalance>
for UnityAssetBalanceConversion
where
InBalance: Into<AssetBalance>,
{
type Error = ();
fn to_asset_balance(balance: InBalance, _: AssetId) -> Result<AssetBalance, Self::Error> {
Ok(balance.into())
}
}
pub struct UnityOrOuterConversion<C, O>(core::marker::PhantomData<(C, O)>);
impl<AssetBalance, AssetId, OutBalance, C, O>
ConversionFromAssetBalance<AssetBalance, AssetId, OutBalance> for UnityOrOuterConversion<C, O>
where
C: Contains<AssetId>,
O: ConversionFromAssetBalance<AssetBalance, AssetId, OutBalance>,
AssetBalance: Into<OutBalance>,
{
type Error = O::Error;
fn from_asset_balance(
balance: AssetBalance,
asset_id: AssetId,
) -> Result<OutBalance, Self::Error> {
if C::contains(&asset_id) {
return Ok(balance.into());
}
O::from_asset_balance(balance, asset_id)
}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_successful(asset_id: AssetId) {
O::ensure_successful(asset_id)
}
}
impl<InBalance, AssetId, AssetBalance, C, O>
ConversionToAssetBalance<InBalance, AssetId, AssetBalance> for UnityOrOuterConversion<C, O>
where
C: Contains<AssetId>,
O: ConversionToAssetBalance<InBalance, AssetId, AssetBalance>,
InBalance: Into<AssetBalance>,
{
type Error = O::Error;
fn to_asset_balance(
balance: InBalance,
asset_id: AssetId,
) -> Result<AssetBalance, Self::Error> {
if C::contains(&asset_id) {
return Ok(balance.into());
}
O::to_asset_balance(balance, asset_id)
}
}
pub trait ProvideAssetReserves<A, R> {
fn reserves(id: &A) -> Vec<R>;
}
impl<A, R> ProvideAssetReserves<A, R> for () {
fn reserves(_id: &A) -> Vec<R> {
vec![]
}
}
pub trait Locker<CollectionId, ItemId> {
fn is_locked(collection: CollectionId, item: ItemId) -> bool;
}
impl<CollectionId, ItemId> Locker<CollectionId, ItemId> for () {
fn is_locked(_collection: CollectionId, _item: ItemId) -> bool {
false
}
}
pub trait GetSalary<Rank, AccountId, Balance> {
fn get_salary(rank: Rank, who: &AccountId) -> Balance;
}
pub struct ConvertRank<C>(core::marker::PhantomData<C>);
impl<A, R, B, C: Convert<R, B>> GetSalary<R, A, B> for ConvertRank<C> {
fn get_salary(rank: R, _: &A) -> B {
C::convert(rank)
}
}
#[derive(
Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, Debug, MaxEncodedLen, TypeInfo,
)]
pub struct IdAmount<Id, Balance> {
pub id: Id,
pub amount: Balance,
}