use crate::traits::misc::{SameOrOther, TryDrop};
use core::ops::Div;
use subsoil::runtime::traits::Saturating;
mod imbalance_accounting;
mod on_unbalanced;
mod signed_imbalance;
mod split_two_ways;
pub use imbalance_accounting::{
ImbalanceAccounting, UnsafeConstructorDestructor, UnsafeManualAccounting,
};
pub use on_unbalanced::{OnUnbalanced, ResolveAssetTo, ResolveTo};
pub use signed_imbalance::SignedImbalance;
pub use split_two_ways::SplitTwoWays;
#[must_use]
pub trait Imbalance<Balance>: Sized + TryDrop + Default + TryMerge {
type Opposite: Imbalance<Balance>;
fn zero() -> Self;
fn drop_zero(self) -> Result<(), Self>;
fn split(self, amount: Balance) -> (Self, Self);
fn extract(&mut self, amount: Balance) -> Self;
fn ration(self, first: u32, second: u32) -> (Self, Self)
where
Balance: From<u32> + Saturating + Div<Output = Balance>,
{
let total: u32 = first.saturating_add(second);
if total == 0 {
return (Self::zero(), Self::zero());
}
let amount1 = self.peek().saturating_mul(first.into()) / total.into();
self.split(amount1)
}
fn split_merge(self, amount: Balance, others: (Self, Self)) -> (Self, Self) {
let (a, b) = self.split(amount);
(a.merge(others.0), b.merge(others.1))
}
fn ration_merge(self, first: u32, second: u32, others: (Self, Self)) -> (Self, Self)
where
Balance: From<u32> + Saturating + Div<Output = Balance>,
{
let (a, b) = self.ration(first, second);
(a.merge(others.0), b.merge(others.1))
}
fn split_merge_into(self, amount: Balance, others: &mut (Self, Self)) {
let (a, b) = self.split(amount);
others.0.subsume(a);
others.1.subsume(b);
}
fn ration_merge_into(self, first: u32, second: u32, others: &mut (Self, Self))
where
Balance: From<u32> + Saturating + Div<Output = Balance>,
{
let (a, b) = self.ration(first, second);
others.0.subsume(a);
others.1.subsume(b);
}
fn merge(self, other: Self) -> Self;
fn merge_into(self, other: &mut Self) {
other.subsume(self)
}
fn maybe_merge(self, other: Option<Self>) -> Self {
if let Some(o) = other {
self.merge(o)
} else {
self
}
}
fn subsume(&mut self, other: Self);
fn maybe_subsume(&mut self, other: Option<Self>) {
if let Some(o) = other {
self.subsume(o)
}
}
fn offset(self, other: Self::Opposite) -> SameOrOther<Self, Self::Opposite>;
fn peek(&self) -> Balance;
}
pub trait TryMerge: Sized {
fn try_merge(self, other: Self) -> Result<Self, (Self, Self)>;
}
#[cfg(feature = "std")]
impl<Balance: Default> Imbalance<Balance> for () {
type Opposite = ();
fn zero() -> Self {
()
}
fn drop_zero(self) -> Result<(), Self> {
Ok(())
}
fn split(self, _: Balance) -> (Self, Self) {
((), ())
}
fn extract(&mut self, _: Balance) -> Self {
()
}
fn ration(self, _: u32, _: u32) -> (Self, Self)
where
Balance: From<u32> + Saturating + Div<Output = Balance>,
{
((), ())
}
fn split_merge(self, _: Balance, _: (Self, Self)) -> (Self, Self) {
((), ())
}
fn ration_merge(self, _: u32, _: u32, _: (Self, Self)) -> (Self, Self)
where
Balance: From<u32> + Saturating + Div<Output = Balance>,
{
((), ())
}
fn split_merge_into(self, _: Balance, _: &mut (Self, Self)) {}
fn ration_merge_into(self, _: u32, _: u32, _: &mut (Self, Self))
where
Balance: From<u32> + Saturating + Div<Output = Balance>,
{
}
fn merge(self, _: Self) -> Self {
()
}
fn merge_into(self, _: &mut Self) {}
fn maybe_merge(self, _: Option<Self>) -> Self {
()
}
fn subsume(&mut self, _: Self) {}
fn maybe_subsume(&mut self, _: Option<Self>) {
()
}
fn offset(self, _: Self::Opposite) -> SameOrOther<Self, Self::Opposite> {
SameOrOther::None
}
fn peek(&self) -> Balance {
Default::default()
}
}
#[cfg(feature = "std")]
impl TryMerge for () {
fn try_merge(self, _: Self) -> Result<Self, (Self, Self)> {
Ok(())
}
}