clerk/journal/printer/amount.go (view raw)
| 1 | package printer |
| 2 | |
| 3 | import ( |
| 4 | "olexsmir.xyz/clerk/internal/decimal" |
| 5 | "olexsmir.xyz/clerk/journal/ast" |
| 6 | ) |
| 7 | |
| 8 | func (p *printer) writeAmount(a *ast.Amount) { |
| 9 | if a == nil { |
| 10 | return |
| 11 | } |
| 12 | |
| 13 | if a.IsExpr { |
| 14 | if a.Expr != "" { |
| 15 | // parenthesized expression, e.g. (amount * 0.5) |
| 16 | p.buf.WriteByte('(') |
| 17 | p.buf.WriteString(a.Expr) |
| 18 | p.buf.WriteByte(')') |
| 19 | return |
| 20 | } else { |
| 21 | // bare scaling expr, e.g. `*-1`, `*.33` — parser stored the value in Quantity |
| 22 | p.buf.WriteByte('*') |
| 23 | } |
| 24 | } |
| 25 | |
| 26 | prec := max(a.QuantityFmt.Precision, 2) |
| 27 | |
| 28 | comm := a.Commodity |
| 29 | if comm == "" { |
| 30 | p.writeDecimal(a.Quantity, a.QuantityFmt, prec) |
| 31 | return |
| 32 | } |
| 33 | |
| 34 | switch p.cfg.CommodityPos { |
| 35 | case CommodityBefore: |
| 36 | p.buf.WriteString(comm) |
| 37 | if a.HasSpace { |
| 38 | p.buf.WriteByte(' ') |
| 39 | } |
| 40 | p.writeDecimal(a.Quantity, a.QuantityFmt, prec) |
| 41 | case CommodityAfter: |
| 42 | p.writeDecimal(a.Quantity, a.QuantityFmt, prec) |
| 43 | if a.HasSpace { |
| 44 | p.buf.WriteByte(' ') |
| 45 | } |
| 46 | p.buf.WriteString(comm) |
| 47 | default: |
| 48 | panic("impossible CommodityPos value") |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | func (p *printer) writeCost(c *ast.Cost) { |
| 53 | if c.IsTotal { |
| 54 | p.buf.WriteString(" @@ ") |
| 55 | } else { |
| 56 | p.buf.WriteString(" @ ") |
| 57 | } |
| 58 | p.writeAmount(&c.Amount) |
| 59 | } |
| 60 | |
| 61 | func (p *printer) writeBalanceAssertion(ba *ast.BalanceAssertion) { |
| 62 | if ba == nil { |
| 63 | return |
| 64 | } |
| 65 | switch { |
| 66 | case ba.IsStrict && ba.IsInclusive: |
| 67 | p.buf.WriteString("=== ") |
| 68 | case ba.IsStrict: |
| 69 | p.buf.WriteString("== ") |
| 70 | case ba.IsInclusive: |
| 71 | p.buf.WriteString("=* ") |
| 72 | default: |
| 73 | p.buf.WriteString("= ") |
| 74 | } |
| 75 | p.writeAmount(&ba.Amount) |
| 76 | if ba.Cost != nil { |
| 77 | p.writeCost(ba.Cost) |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | func (p *printer) writeDecimal(d decimal.Decimal, fmt ast.QuantityFormat, forcePrec int) { |
| 82 | d.WriteFixed(&p.buf, forcePrec, fmt.Decimal, fmt.Thousands) |
| 83 | } |