tktax_histogram/
histogram_bin.rs

1// ---------------- [ File: tktax-histogram/src/histogram_bin.rs ]
2crate::ix!();
3
4#[derive(Builder,Clone,Getters,Debug,PartialEq,Eq)]
5#[getset(get="pub")]
6#[builder(setter(into))]
7pub struct HistogramMonthBinTxn {
8    date:        NaiveDate,
9    amount:      MonetaryAmount,
10    description: String,
11}
12
13impl fmt::Display for HistogramMonthBinTxn {
14
15    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16        write!(
17            f, 
18            "{} {} {}", 
19            self.date, 
20            self.amount, 
21            self.description
22        )
23    }
24}
25
26#[derive(Builder,Getters,Debug,PartialEq,Eq)]
27#[getset(get="pub")]
28#[builder(setter(into))]
29pub struct HistogramMonthBin {
30    price_range: Range<MonetaryAmount>,
31    txns:        Vec<HistogramMonthBinTxn>,
32}
33
34impl HistogramMonthBin {
35
36    pub fn len(&self) -> usize {
37        self.txns.len()
38    }
39
40    pub fn price_lo(&self) -> MonetaryAmount {
41        self.price_range.start
42    }
43
44    pub fn price_hi(&self) -> MonetaryAmount {
45        self.price_range.end
46    }
47
48    pub fn ntx(&self) -> usize {
49        self.txns.len()
50    }
51
52    pub fn fmt_bin_header(
53        &self, 
54        f: &mut fmt::Formatter<'_>) -> fmt::Result 
55    {
56        // Assuming price_lo() and price_hi() return types that implement Display
57        // Convert them to String to be able to trim
58        let price_lo_str = format!("{}", self.price_lo()).trim().to_string();
59        let price_hi_str = format!("{}", self.price_hi()).trim().to_string();
60
61        // Construct the range string
62        let range_str = format!("[ {} to {} ]:", price_lo_str, price_hi_str);
63
64        // Decide on the fixed width for the range part, e.g., 30 characters
65        let fixed_width = 30;
66
67        // Format the range string with fixed width, right-padding with spaces if needed
68        let range_str_fixed_width = format!("{:width$}", range_str, width = fixed_width);
69
70        // Now, include the fixed width range string and the number of transactions in your output
71        writeln!(
72            f,
73            "{} {:3} transactions",
74            range_str_fixed_width,
75            self.ntx()
76        );
77
78        write!(f, "")
79    }
80
81    pub(crate) fn fmt_short(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82
83        self.fmt_bin_header(f)?;
84
85        write!(f, "")
86    }
87
88    pub(crate) fn fmt_and_show_most_populous_bins(
89        &self, 
90        f: &mut fmt::Formatter<'_>, 
91        threshold_item_count_in_bin: usize) -> fmt::Result 
92    {
93        self.fmt_bin_header(f)?;
94
95        // Display transaction details for heavier bins
96        if self.ntx() >= threshold_item_count_in_bin {
97
98            for tx in &self.txns {
99
100                if !self.price_range.contains(&tx.amount) {
101                    panic!("bad price {} for range {:?}", tx.amount, self.price_range);
102                }
103
104                writeln!(f, "    {}", tx)?;
105            }
106        }
107
108        write!(f, "")
109    }
110
111    pub fn fmt_and_show_heavy_transactions(
112        &self, 
113        f: &mut fmt::Formatter<'_>, 
114        maybe_price_threshold: Option<MonetaryAmount>) -> fmt::Result 
115    {
116        self.fmt_bin_header(f)?;
117
118        // Display transaction details for bins with a higher price range
119        if maybe_price_threshold.is_none() || self.price_lo() >= maybe_price_threshold.unwrap() {
120
121            for tx in &self.txns {
122
123                if !self.price_range.contains(&tx.amount) {
124                    panic!("bad price {} for range {:?}", tx.amount, self.price_range);
125                }
126
127                writeln!(f, "    {}", tx)?;
128            }
129
130            writeln!(f, " ")?;
131        }
132
133        write!(f, "")
134    }
135}