diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 9348c38..8233e8d 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -4,7 +4,6 @@ import ( "flag" "fmt" "io" - "maps" "os" "slices" @@ -101,14 +100,7 @@ func Main() { for _, date := range register.Dates() { balances := register[date] - newBalances := make(ledger.Balances) - for k, v := range balances { - if got := prev[k]; !maps.Equal(v, got) { - newBalances[k] = v - } - } - - if len(newBalances) > 0 { + if newBalances := balances.Sub(prev).Nonzero(); len(newBalances) > 0 { fmt.Println(date) FPrintBalances(os.Stdout, newBalances) } diff --git a/src/ledger/balances.go b/src/ledger/balances.go index 7d6d519..dd61694 100644 --- a/src/ledger/balances.go +++ b/src/ledger/balances.go @@ -11,6 +11,30 @@ type Balances map[string]Balance type Balance map[Currency]float64 +func (balances Balances) Sub(other Balances) Balances { + result := make(Balances) + for k, v := range balances { + result[k] = v.Sub(other[k]) + } + for k, v := range other { + if _, ok := balances[k]; ok { + continue + } + result[k] = v.Invert() + } + return result +} + +func (balances Balances) Nonzero() Balances { + result := make(Balances) + for k, v := range balances { + if nonzero := v.Nonzero(); len(nonzero) > 0 { + result[k] = nonzero + } + } + return result +} + func (balances Balances) NotLike(pattern string) Balances { result := make(Balances) p := regexp.MustCompile(pattern) @@ -98,6 +122,39 @@ func (balances Balances) Push(d Delta) { balances[d.Name].Push(d) } +func (balance Balance) Sub(other Balance) Balance { + return balance.Sum(other.Invert()) +} + +func (balance Balance) Sum(other Balance) Balance { + result := make(Balance) + for k, v := range balance { + result[k] += v + } + for k, v := range other { + result[k] += v + } + return result +} + +func (balance Balance) Nonzero() Balance { + result := make(Balance) + for k, v := range balance { + if v != 0 { + result[k] = v + } + } + return result +} + +func (balance Balance) Invert() Balance { + result := make(Balance) + for k, v := range balance { + result[k] = v * -1.0 + } + return result +} + func (balance Balance) Push(d Delta) { if _, ok := balance[d.Currency]; !ok { balance[d.Currency] = 0