all repos

clerk @ 2f348cb

missing tooling for ledger/hledger

clerk/journal/ast/ast.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
extact all ast.Date to string code into .String() method, 1 month ago
1
package ast
2
3
import (
4
	"fmt"
5
	"strings"
6
7
	"olexsmir.xyz/clerk/journal/token"
8
)
9
10
type Journal struct {
11
	Entries []Entry
12
	Errors  []*ParseError
13
}
14
15
type Entry interface {
16
	entryNode()
17
}
18
19
type ParseError struct {
20
	Span    token.Span
21
	Message string
22
}
23
24
type FileError struct {
25
	Path    string
26
	Span    token.Span
27
	Message string
28
}
29
30
type Date struct {
31
	Year, Month, Day int
32
	Sep              byte // '-' '/' '.'
33
	Span             token.Span
34
}
35
36
// Compare returns -1 if d is before other, 0 if equal, 1 if after.
37
func (d Date) Compare(other Date) int {
38
	if d.Year != other.Year {
39
		if d.Year < other.Year {
40
			return -1
41
		}
42
		return 1
43
	}
44
	if d.Month != other.Month {
45
		if d.Month < other.Month {
46
			return -1
47
		}
48
		return 1
49
	}
50
	if d.Day != other.Day {
51
		if d.Day < other.Day {
52
			return -1
53
		}
54
		return 1
55
	}
56
	return 0
57
}
58
59
// String renders d as "YYYY-MM-DD", or "" for an unset or invalid date.
60
func (d Date) String() string {
61
	if (d.Year == 0 && d.Month == 0 && d.Day == 0) ||
62
		(d.Month < 1 || d.Month > 12 || d.Day < 1 || d.Day > 31) {
63
		return ""
64
	}
65
	return fmt.Sprintf("%04d-%02d-%02d", d.Year, d.Month, d.Day)
66
}
67
68
type Time struct {
69
	Hour, Minute, Second int
70
	Span                 token.Span
71
}
72
73
type DateTime struct {
74
	Date Date
75
	Time *Time
76
	Span token.Span
77
}
78
79
type Tag struct {
80
	Key, Value string
81
	Span       token.Span
82
}
83
84
type Comment struct {
85
	Marker byte // ';' '#' '%' '*'
86
	Tags   []Tag
87
	Text   string
88
	Span   token.Span
89
}
90
91
func (Comment) entryNode() {}
92
93
type StatusType int
94
95
func (s StatusType) String() string {
96
	switch s {
97
	case StatusCleared:
98
		return "*"
99
	case StatusPending:
100
		return "!"
101
	case StatusNone:
102
		return ""
103
	default:
104
		panic("unreachable")
105
	}
106
}
107
108
const (
109
	StatusNone    StatusType = iota // not set
110
	StatusCleared                   // * cleared
111
	StatusPending                   // ! pending
112
)
113
114
type Status struct {
115
	Value StatusType
116
	Span  token.Span
117
}
118
119
type Code struct {
120
	Value string
121
	Span  token.Span
122
}
123
124
type Note struct {
125
	Value string
126
	Span  token.Span
127
}
128
129
type Description struct {
130
	Value string
131
	Span  token.Span
132
}
133
134
type Expr struct {
135
	Value string
136
	Span  token.Span
137
}
138
139
type Payee struct {
140
	Name string
141
	Span token.Span
142
}
143
144
type SubAccount struct {
145
	Name string
146
	Span token.Span
147
}
148
149
type Account struct {
150
	Name []SubAccount // ['expenses' 'food']
151
	Span token.Span
152
}
153
154
func (a Account) String() string {
155
	if len(a.Name) == 0 {
156
		return ""
157
	}
158
	var name strings.Builder
159
	name.Grow(len(a.Name))
160
	name.WriteString(a.Name[0].Name)
161
	for _, s := range a.Name[1:] {
162
		name.WriteByte(':')
163
		name.WriteString(s.Name)
164
	}
165
	return name.String()
166
}