-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprice.go
93 lines (82 loc) · 1.89 KB
/
price.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package coin
import (
"encoding/json"
"fmt"
"io"
"strings"
"time"
"github.com/mkobetic/coin/rex"
)
type Price struct {
Commodity *Commodity
Currency *Commodity
Value *Amount
Time time.Time
CommodityId string
currencyId string
line uint
file string
}
var Prices []*Price
func (p *Price) Write(w io.Writer, ledger bool) error {
date := p.Time.Format(DateFormat)
_, err := io.WriteString(w, "P "+date+" "+p.Commodity.SafeId(ledger)+" ")
if err != nil {
return err
}
err = p.Value.Write(w, ledger)
if err != nil {
return err
}
_, err = io.WriteString(w, "\n")
return err
}
var priceREX = rex.MustCompile(`P %s\s+%s\s+%s`, DateREX, CommodityREX, AmountREX)
func (p *Parser) parsePrice(fn string) (*Price, error) {
match := priceREX.Match(p.Bytes())
if match == nil {
return nil, fmt.Errorf("invalid price line")
}
date := mustParseDate(match, 0)
currencyId := string(match["commodity2"])
line := p.lineNr
location := fmt.Sprintf("%s:%d", fn, line)
c := MustFindCommodity(currencyId, location)
amt, err := parseAmount(match["amount"], c)
if err != nil {
return nil, err
}
commodityId := string(match["commodity1"])
p.Scan() // advance to next line before returning
return &Price{
Time: date,
Value: amt,
CommodityId: commodityId,
currencyId: currencyId,
line: line,
file: fn,
}, nil
}
func (p *Price) String() string {
var b strings.Builder
p.Write(&b, false)
return b.String()
}
func (p *Price) Location() string {
if p.file == "" {
return ""
}
return fmt.Sprintf("%s:%d", p.file, p.line)
}
func (p *Price) MarshalJSON() ([]byte, error) {
value := map[string]interface{}{
"time": p.Time.Format(DateFormat),
"commodity": p.Commodity.Id,
"currency": p.Currency.Id,
"value": p.Value,
}
if p.Location() != "" {
value["location"] = p.Location()
}
return json.MarshalIndent(value, "", "\t")
}