tktax-histogram 0.2.2

A Rust crate that provides robust monthly histogram utilities for financial transactions, using specialized types from the TKTAX ecosystem.
Documentation
// ---------------- [ File: tktax-histogram/src/histogram_builder.rs ]
crate::ix!();

#[derive(Getters)]
#[getset(get="pub")]
pub struct AccountHistogramBuilder<'a> {
    account: &'a Account,
    bins:    Vec<MonetaryAmount>,
}

impl<'a> AccountHistogramBuilder<'a> {

    pub fn new(account: &'a Account, bins: Vec<MonetaryAmount>) -> Self {
        Self { account, bins }
    }

    pub fn build_histogram(&self, strategy: &HistogramDisplayStrategy) -> AccountHistogram {

        let mut histogram = AccountHistogram::new(strategy);

        let full_data = self.organize_histogram_data();

        // Collect and sort the months
        let mut months: Vec<NaiveDate> = full_data.keys().cloned().collect();

        months.sort();

        for month in &months {

            let bins = full_data.get(month).unwrap();

            let month_number = month.month();

            let mut histogram_month = HistogramMonth::new(month_number);

            for (i, bin) in bins.iter().enumerate()
                //.filter(|(i,bin)| bin.len() > 0) 
            {
                let month_txns: Vec<_> = bin.iter().sorted().rev().map(
                    |tx| HistogramMonthBinTxnBuilder::default()
                        .date(*tx.transaction_date())
                        .amount(tx.amount())
                        .description(tx.description())
                        .build()
                        .unwrap()
                ).collect();

                histogram_month.push(
                    HistogramMonthBinBuilder::default()
                        .price_range(self.bins[i] .. self.bins[i + 1])
                        .txns(month_txns)
                        .build()
                        .unwrap()
                );
            }

            histogram.push(histogram_month);
        }

        histogram
    }

    fn organize_histogram_data(&self) -> HashMap<NaiveDate, Vec<Vec<&'a Transaction>>> {

        let mut histograms: HashMap<NaiveDate, Vec<Vec<&'a Transaction>>> = HashMap::new();

        for tx in self.account.txns().iter() {

            let month_start = tx.transaction_date().with_day0(0).unwrap();

            let histogram = histograms.entry(month_start).or_insert_with(|| {
                let mut bin_vec = Vec::new();
                for _ in 0..self.bins.len() - 1 {
                    bin_vec.push(Vec::new());
                }
                bin_vec
            });

            for i in 0..self.bins.len() - 1 {
                if tx.amount() >= self.bins[i] && tx.amount() < self.bins[i + 1] {
                    histogram[i].push(tx);
                    break;
                }
            }
        }

        histograms
    }
}