12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- use std::collections::BTreeMap;
- use itertools::Itertools;
- use crate::data::{Root, SourceFile, Span, Spanned};
- use super::{LedgerEntry, Transaction};
- fn print_transaction(root: &Root, tx: &Transaction, padding: usize) {
- println!(
- "{}: {}",
- tx.datestamp,
- tx.title.as_deref().unwrap_or("")
- );
- if !tx.annotations.is_empty() {
- println!(
- " {}",
- tx.annotations.iter().map(|a| format!("[{a}]")).join(" ")
- );
- }
- let force_show = tx.changes.iter().unique_by(|b| *b.account).count() > 1;
- for change in &tx.changes {
- let spacer = if change.amount.is_sign_positive() {
- " "
- } else {
- ""
- };
- let balance = if let Some(bal) = change.balance {
- format!(" = {bal}")
- } else {
- String::new()
- };
- if Some(change.unit.as_ref()) == root.account_spec(*change.account).unwrap().unit.as_ref()
- && !force_show
- {
- println!(" - {:padding$}: {spacer}{}{balance}", change.account, change.amount,);
- } else {
- println!(
- " - {:padding$}: {spacer}{}{balance} {}",
- change.account, change.amount, change.unit,
- );
- }
- }
- // empty line afterwards
- println!();
- }
- fn print_comment(c: &Spanned<String>) {
- println!("{c}");
- }
- pub fn print_ledger<'l>(root: &Root, entries: impl Iterator<Item = &'l LedgerEntry>) {
- let mut ordering = BTreeMap::<SourceFile, BTreeMap<Span, &LedgerEntry>>::new();
- entries.for_each(|e| {
- ordering
- .entry(e.span().context)
- .or_default()
- .insert(e.span(), &e);
- });
- let Some(padding) = root.spec_root.accounts.keys().map(|k| k.len()).max() else {
- // no accounts
- return;
- };
- for (filename, entries) in ordering {
- println!(
- "==== file {} ====",
- std::path::Path::new(filename.as_ref()).display()
- );
- for (_span, le) in entries {
- match le {
- LedgerEntry::Transaction(tx) => print_transaction(root, tx, padding),
- LedgerEntry::Comment(c) => print_comment(c),
- }
- }
- }
- }
|