bean_rs/
utils.rs

1use log::debug;
2use pest::iterators::Pair;
3
4use crate::data::{AccBal, Directive};
5use crate::error::BeanError;
6use crate::grammar::Rule;
7
8pub fn debug_directives(directives: &Vec<Directive>) {
9    for d in directives {
10        debug!("{d}")
11    }
12}
13
14pub fn print_directives(directives: &Vec<Directive>) {
15    for d in directives {
16        println!("{d}")
17    }
18}
19
20pub fn print_bals(bals: AccBal) {
21    println!("-- Balances --");
22    for (acc, ccy_bals) in bals {
23        for (ccy, amount) in ccy_bals {
24            println!("{acc} {amount} {ccy}");
25        }
26    }
27}
28
29pub fn print_errors(errs: &Vec<BeanError>) {
30    if !errs.is_empty() {
31        eprintln!("-- Errors -- ");
32    }
33    for e in errs {
34        eprintln!("{e}");
35    }
36}
37
38pub fn debug_pair(pair: &Pair<Rule>, depth: usize) {
39    if depth == 0 {
40        debug!("full parse output");
41    }
42
43    let indent = "  ".repeat(depth);
44    let inner_pairs: Vec<Pair<Rule>> = pair.clone().into_inner().collect();
45
46    if inner_pairs.is_empty() {
47        // It's a leaf node
48        debug!("{}{:?}: {}", indent, pair.as_rule(), pair.as_str());
49    } else {
50        // Not a leaf node, just print the rule
51        debug!("{}{:?}:", indent, pair.as_rule());
52        for inner_pair in inner_pairs {
53            debug_pair(&inner_pair, depth + 1);
54        }
55    }
56    if depth == 0 {
57        debug!("END full parse output");
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use std::collections::HashMap;
64
65    use chrono::NaiveDate;
66    use rust_decimal::Decimal;
67
68    use crate::{
69        data::{CcyBal, Commodity, DebugLine},
70        error::ErrorType,
71    };
72
73    use super::*;
74
75    #[test]
76    fn useless_debug_directives() {
77        let comm = Commodity {
78            date: NaiveDate::from_ymd_opt(2000, 1, 1).unwrap(),
79            ccy: "USD".to_string(),
80            meta: vec![],
81            debug: DebugLine { line: 0 },
82        };
83        let vec = vec![Directive::Commodity(comm)];
84        debug_directives(&vec)
85    }
86
87    #[test]
88    fn test_print_bals() {
89        let mut bals: AccBal = HashMap::new();
90        let mut ccybal: CcyBal = HashMap::new();
91        ccybal.insert("USD".to_string(), Decimal::new(100, 1));
92        bals.insert("Assets:Checking".to_string(), ccybal);
93        print_bals(bals);
94    }
95
96    #[test]
97    fn test_print_errors() {
98        let comm = Commodity {
99            date: NaiveDate::from_ymd_opt(2000, 1, 1).unwrap(),
100            ccy: "USD".to_string(),
101            meta: vec![],
102            debug: DebugLine { line: 0 },
103        };
104        let err = BeanError::new(
105            ErrorType::Badline,
106            &DebugLine { line: 0 },
107            "",
108            Some(&Directive::Commodity(comm)),
109        );
110        let errs = vec![err];
111        print_errors(&errs);
112    }
113}