print.rs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. use std::collections::BTreeMap;
  2. use itertools::Itertools;
  3. use crate::data::{Root, SourceFile, Span, Spanned};
  4. use super::{Balance, LedgerEntry};
  5. fn print_ledger_entry(root: &Root, entry: &LedgerEntry, padding: usize) {
  6. println!(
  7. "{}-{:02}-{:02}: {}",
  8. entry.datestamp.0,
  9. entry.datestamp.1,
  10. entry.datestamp.2,
  11. entry.title.as_ref().map(String::as_str).unwrap_or("")
  12. );
  13. let force_show = entry.balances.iter().unique_by(|b| *b.account).count() > 1;
  14. for bal in &entry.balances {
  15. let spacer = if bal.amount.is_sign_positive() {
  16. " "
  17. } else {
  18. ""
  19. };
  20. if Some(bal.unit.as_ref()) == root.account_spec(*bal.account).unwrap().unit.as_ref()
  21. && !force_show
  22. {
  23. println!(
  24. " - {:padding$}: {spacer}{}",
  25. bal.account,
  26. bal.amount,
  27. padding = padding
  28. );
  29. } else {
  30. println!(
  31. " - {:padding$}: {spacer}{} {}",
  32. bal.account,
  33. bal.amount,
  34. bal.unit,
  35. padding = padding
  36. );
  37. }
  38. }
  39. // empty line afterwards
  40. println!("");
  41. }
  42. pub fn print_ledger<'l>(root: &Root, entries: impl Iterator<Item = &'l Spanned<LedgerEntry>>) {
  43. let mut ordering = BTreeMap::<SourceFile, BTreeMap<Span, &LedgerEntry>>::new();
  44. entries.for_each(|e| {
  45. ordering
  46. .entry(e.span().context)
  47. .or_default()
  48. .insert(e.span(), e.as_ref());
  49. });
  50. let Some(padding) = root.spec_root.accounts.keys().map(|k| k.len()).max() else {
  51. // no accounts
  52. return;
  53. };
  54. for (filename, entries) in ordering {
  55. println!(
  56. "==== file {} ====",
  57. std::path::Path::new(filename.as_ref()).display()
  58. );
  59. for (_span, le) in entries {
  60. print_ledger_entry(root, le, padding);
  61. }
  62. }
  63. }