Files
any2anexoj/internal/aggregator_writer.go

79 lines
1.5 KiB
Go

package internal
import (
"context"
"iter"
"sync"
"github.com/shopspring/decimal"
)
// AggregatorWriter tracks ReportItem totals.
type AggregatorWriter struct {
mu sync.RWMutex
items []ReportItem
totalEarned decimal.Decimal
totalSpent decimal.Decimal
totalFees decimal.Decimal
totalTaxes decimal.Decimal
}
func NewAggregatorWriter() *AggregatorWriter {
return &AggregatorWriter{}
}
func (aw *AggregatorWriter) Write(_ context.Context, ri ReportItem) error {
aw.mu.Lock()
defer aw.mu.Unlock()
aw.items = append(aw.items, ri)
aw.totalEarned = aw.totalEarned.Add(ri.SellValue.Round(2))
aw.totalSpent = aw.totalSpent.Add(ri.BuyValue.Round(2))
aw.totalFees = aw.totalFees.Add(ri.Fees.Round(2))
aw.totalTaxes = aw.totalTaxes.Add(ri.Taxes.Round(2))
return nil
}
func (aw *AggregatorWriter) Iter() iter.Seq[ReportItem] {
aw.mu.RLock()
itemsCopy := make([]ReportItem, len(aw.items))
copy(itemsCopy, aw.items)
aw.mu.RUnlock()
return func(yield func(ReportItem) bool) {
for _, ri := range itemsCopy {
if !yield(ri) {
return
}
}
}
}
func (aw *AggregatorWriter) TotalEarned() decimal.Decimal {
aw.mu.RLock()
defer aw.mu.RUnlock()
return aw.totalEarned
}
func (aw *AggregatorWriter) TotalSpent() decimal.Decimal {
aw.mu.RLock()
defer aw.mu.RUnlock()
return aw.totalSpent
}
func (aw *AggregatorWriter) TotalFees() decimal.Decimal {
aw.mu.RLock()
defer aw.mu.RUnlock()
return aw.totalFees
}
func (aw *AggregatorWriter) TotalTaxes() decimal.Decimal {
aw.mu.RLock()
defer aw.mu.RUnlock()
return aw.totalTaxes
}