use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
use core::marker::PhantomData;
use frame_support::traits::Get;
use sp_runtime::{
traits::{Convert, MaybeEquivalence},
Either,
Either::{Left, Right},
};
use xcm::latest::Location;
#[derive(
Clone,
Debug,
Encode,
Decode,
DecodeWithMemTracking,
PartialEq,
Eq,
scale_info::TypeInfo,
MaxEncodedLen,
serde::Serialize,
serde::Deserialize,
)]
pub struct ForeignAssetReserveData {
pub reserve: Location,
pub teleportable: bool,
}
impl From<(Location, bool)> for ForeignAssetReserveData {
fn from((reserve, teleportable): (Location, bool)) -> Self {
ForeignAssetReserveData { reserve, teleportable }
}
}
pub struct TargetFromLeft<Target, L = Location>(PhantomData<(Target, L)>);
impl<Target: Get<L>, L: PartialEq + Eq> Convert<L, Either<(), L>> for TargetFromLeft<Target, L> {
fn convert(l: L) -> Either<(), L> {
Target::get().eq(&l).then(|| Left(())).map_or(Right(l), |n| n)
}
}
pub struct LocalFromLeft<Equivalence, AssetId, L = Location>(
PhantomData<(Equivalence, AssetId, L)>,
);
impl<Equivalence, AssetId, L> Convert<L, Either<AssetId, L>>
for LocalFromLeft<Equivalence, AssetId, L>
where
Equivalence: MaybeEquivalence<L, AssetId>,
{
fn convert(l: L) -> Either<AssetId, L> {
match Equivalence::convert(&l) {
Some(id) => Left(id),
None => Right(l),
}
}
}