use core::marker::PhantomData;
use subsoil::core::TypedGet;
use topsoil_core::traits::{fungible, fungibles, misc::TryDrop};
pub trait OnUnbalanced<Imbalance: TryDrop> {
fn on_unbalanceds(mut amounts: impl Iterator<Item = Imbalance>)
where
Imbalance: crate::traits::tokens::imbalance::TryMerge,
{
let mut sum: Option<Imbalance> = None;
while let Some(next) = amounts.next() {
sum = match sum {
Some(sum) => match sum.try_merge(next) {
Ok(sum) => Some(sum),
Err((sum, next)) => {
Self::on_unbalanced(next);
Some(sum)
},
},
None => Some(next),
}
}
if let Some(sum) = sum {
Self::on_unbalanced(sum)
}
}
fn on_unbalanced(amount: Imbalance) {
amount.try_drop().unwrap_or_else(Self::on_nonzero_unbalanced)
}
fn on_nonzero_unbalanced(amount: Imbalance) {
drop(amount);
}
}
impl<Imbalance: TryDrop> OnUnbalanced<Imbalance> for () {}
pub struct ResolveTo<A, F>(PhantomData<(A, F)>);
impl<A: TypedGet, F: fungible::Balanced<A::Type>> OnUnbalanced<fungible::Credit<A::Type, F>>
for ResolveTo<A, F>
{
fn on_nonzero_unbalanced(credit: fungible::Credit<A::Type, F>) {
let _ = F::resolve(&A::get(), credit).map_err(|c| drop(c));
}
}
pub struct ResolveAssetTo<A, F>(PhantomData<(A, F)>);
impl<A: TypedGet, F: fungibles::Balanced<A::Type>> OnUnbalanced<fungibles::Credit<A::Type, F>>
for ResolveAssetTo<A, F>
{
fn on_nonzero_unbalanced(credit: fungibles::Credit<A::Type, F>) {
let _ = F::resolve(&A::get(), credit).map_err(|c| drop(c));
}
}