use crate::{bnb::BnbMetric, float::Ordf32, ChangePolicy, CoinSelector, Drain, Target};
mod lowest_fee;
pub use lowest_fee::*;
mod changeless;
pub use changeless::*;
fn change_lower_bound(cs: &CoinSelector, target: Target, change_policy: ChangePolicy) -> Drain {
let has_change_now = cs.drain_value(target, change_policy).is_some();
if has_change_now {
let mut least_excess = cs.clone();
cs.unselected()
.rev()
.take_while(|(_, wv)| wv.effective_value(target.fee.rate) < 0.0)
.for_each(|(index, _)| {
least_excess.select(index);
});
least_excess.drain(target, change_policy)
} else {
Drain::NONE
}
}
macro_rules! impl_for_tuple {
($($a:ident $b:tt)*) => {
impl<$($a),*> BnbMetric for ($(($a, f32)),*)
where $($a: BnbMetric),*
{
#[allow(unused)]
fn score(&mut self, cs: &CoinSelector<'_>) -> Option<crate::float::Ordf32> {
let mut acc = Option::<f32>::None;
for (score, ratio) in [$((self.$b.0.score(cs)?, self.$b.1)),*] {
let score: Ordf32 = score;
let ratio: f32 = ratio;
match &mut acc {
Some(acc) => *acc += score.0 * ratio,
acc => *acc = Some(score.0 * ratio),
}
}
acc.map(Ordf32)
}
#[allow(unused)]
fn bound(&mut self, cs: &CoinSelector<'_>) -> Option<crate::float::Ordf32> {
let mut acc = Option::<f32>::None;
for (score, ratio) in [$((self.$b.0.bound(cs)?, self.$b.1)),*] {
let score: Ordf32 = score;
let ratio: f32 = ratio;
match &mut acc {
Some(acc) => *acc += score.0 * ratio,
acc => *acc = Some(score.0 * ratio),
}
}
acc.map(Ordf32)
}
#[allow(unused)]
fn requires_ordering_by_descending_value_pwu(&self) -> bool {
[$(self.$b.0.requires_ordering_by_descending_value_pwu()),*].iter().all(|x| *x)
}
}
};
}
impl_for_tuple!();
impl_for_tuple!(A 0 B 1);
impl_for_tuple!(A 0 B 1 C 2);
impl_for_tuple!(A 0 B 1 C 2 D 3);
impl_for_tuple!(A 0 B 1 C 2 D 3 E 4);