use std::ops::Add;
use get_size2::GetSize;
use neptune_consensus::type_scripts::native_currency_amount::NativeCurrencyAmount;
use crate::upgrade_incentive::UpgradeIncentive;
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, GetSize)]
#[cfg_attr(any(test, feature = "test-helpers"), derive(serde::Serialize))]
#[cfg_attr(any(test, feature = "arbitrary-impls"), derive(arbitrary::Arbitrary))]
pub enum UpgradePriority {
#[default]
Irrelevant,
Interested(NativeCurrencyAmount),
Critical,
}
impl From<UpgradeIncentive> for UpgradePriority {
fn from(incentive: UpgradeIncentive) -> Self {
match incentive {
UpgradeIncentive::Gobble(amount) => UpgradePriority::Interested(amount),
UpgradeIncentive::BalanceAffecting(amount) => UpgradePriority::Interested(amount),
UpgradeIncentive::Critical => UpgradePriority::Critical,
}
}
}
impl PartialOrd for UpgradePriority {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for UpgradePriority {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
use std::cmp::Ordering::Equal;
use std::cmp::Ordering::Greater;
use std::cmp::Ordering::Less;
use UpgradePriority::Critical;
use UpgradePriority::Interested;
use UpgradePriority::Irrelevant;
match (self, other) {
(Irrelevant, Irrelevant) => Equal,
(Irrelevant, _) => Less,
(Interested(_), Irrelevant) => Greater,
(Interested(self_amt), Interested(other_amt)) => self_amt.cmp(other_amt),
(Interested(_), Critical) => Less,
(Critical, Critical) => Equal,
(Critical, _) => Greater,
}
}
}
impl UpgradePriority {
pub fn is_irrelevant(&self) -> bool {
*self == UpgradePriority::Irrelevant
}
pub fn incentive_given_gobble_potential(
&self,
gobbling_potential: NativeCurrencyAmount,
) -> UpgradeIncentive {
use UpgradePriority::Critical;
use UpgradePriority::Interested;
use UpgradePriority::Irrelevant;
match self {
Irrelevant => UpgradeIncentive::Gobble(gobbling_potential),
Interested(native_currency_amount) => {
UpgradeIncentive::BalanceAffecting(*native_currency_amount)
}
Critical => UpgradeIncentive::Critical,
}
}
}
impl Add for UpgradePriority {
type Output = Self;
fn add(self, other: Self) -> Self::Output {
use UpgradePriority::Critical;
use UpgradePriority::Interested;
use UpgradePriority::Irrelevant;
match (self, other) {
(Irrelevant, _) => other,
(_, Irrelevant) => self,
(Interested(self_amt), Interested(other_amt)) => Interested(self_amt + other_amt),
(_, Critical) | (Critical, _) => Critical,
}
}
}