split/src/strategy.rs

61 lines
2.0 KiB
Rust

// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::collections::HashMap;
use std::rc::Rc;
use rust_decimal::prelude::*;
use rust_decimal_macros::dec;
use crate::actor::*;
use crate::purchase::*;
// key is a string for getting Eq and PartialEq w object safety
pub type ShareHashMap = HashMap<String, (Rc<dyn Actor>, Decimal)>;
/*
* SPLITTING STRATEGIES:
* Unequal: Each actor's split is specified in specific amounts
* Shares: Each actor's split is specified in specific percentage
* Equal: Each actor's split is computed by splitting total expense among all participating actors
*/
#[derive(Clone)]
pub enum SplitStrategy {
Unequal(ShareHashMap),
Shares(ShareHashMap),
Equal,
}
impl SplitStrategy {
pub(crate) fn validate(&self, purchase: &dyn Purchasable) -> bool {
match self {
SplitStrategy::Unequal(shares) => {
let mut total = dec!(0.00);
for (_actor_str, (_actor_obj, share)) in shares.iter() {
total += share;
}
let cost = purchase.cost();
println!("Unequal sharing: expected {cost} got {total}");
total == cost
}
SplitStrategy::Shares(shares) => {
let mut total = dec!(0.00);
let cost = purchase.cost();
let mut total_shares = dec!(0.00);
for (_actor_str, (_actor_obj, share)) in shares.iter() {
total_shares += share;
total += cost * share;
println!("Shares: {:?}, total: {total_shares}", share);
}
println!("Unequal sharing: expected shares 1 got {total_shares}");
println!("Unequal sharing: expected {cost} got {total}");
total_shares == dec!(1.00) && total == cost
}
SplitStrategy::Equal => true,
}
}
}