-
Notifications
You must be signed in to change notification settings - Fork 0
/
reader.go
72 lines (61 loc) · 1.61 KB
/
reader.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
package csv
import (
"encoding/csv"
"fmt"
"io"
"golang.org/x/text/encoding/japanese"
"golang.org/x/text/transform"
)
var headerLabels = [10]string{
"計算対象", "日付", "内容", "金額(円)", "保有金融機関", "大項目", "中項目", "メモ", "振替", "ID",
}
// Reader reads records from money forward csv file.
type Reader struct {
reader *csv.Reader
// If IgnoreHeader is true, ignore header record when read. Default is true.
IgnoreHeader bool
// If isHeaderIgnored is true, the header has already ignored.
isHeaderIgnored bool
}
// NewReader returns a new reader that reads from r.
func NewReader(r io.Reader) *Reader {
rr := transform.NewReader(r, japanese.ShiftJIS.NewDecoder())
return &Reader{
reader: csv.NewReader(rr),
IgnoreHeader: true,
}
}
// Read reads one record from r.
func (r *Reader) Read() ([]string, error) {
record, err := r.reader.Read()
if err == io.EOF {
return nil, err
}
if err != nil {
return nil, fmt.Errorf("failed to read: %w", err)
}
if r.IgnoreHeader && !r.isHeaderIgnored {
if r.isHeaderRecord(record) {
r.isHeaderIgnored = true
return r.Read()
}
}
return record, nil
}
// ReadAll reads all the remaining records from r.
func (r *Reader) ReadAll() ([][]string, error) {
records, err := r.reader.ReadAll()
if err != nil {
return nil, fmt.Errorf("failed to ReadAll: %w", err)
}
if r.IgnoreHeader && !r.isHeaderIgnored {
if r.isHeaderRecord(records[0]) {
r.isHeaderIgnored = true
return records[1:], nil
}
}
return records, nil
}
func (r *Reader) isHeaderRecord(record []string) bool {
return record[0] == headerLabels[0]
}