forked from shoobyban/filehelper
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstruct.go
75 lines (67 loc) · 1.81 KB
/
struct.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
package filehelper
import (
"errors"
"fmt"
"io"
"os"
csvmap "github.com/recursionpharma/go-csv-map"
"github.com/shoobyban/mxj"
"github.com/shoobyban/slog"
)
// ParserFunc is to parse a []byte into an interface{}
type ParserFunc func(io.Reader) (interface{}, error)
// Parser is the main type
type Parser struct {
parsers map[string]ParserFunc
}
// NewParser defines a new parser
func NewParser() *Parser {
return &Parser{
parsers: map[string]ParserFunc{
"xml": func(content io.Reader) (interface{}, error) {
return mxj.NewMapXmlReader(content)
},
"json": func(content io.Reader) (interface{}, error) {
return mxj.NewMapJsonReader(content)
},
"csv": func(content io.Reader) (interface{}, error) {
r := csvmap.NewReader(content)
r.Reader.LazyQuotes = true
var err error
r.Columns, err = r.ReadHeader()
if err != nil {
slog.Errorf("Error reading csv header %v", err)
}
return r.ReadAll()
},
},
}
}
// RegisterParser registers or overrides a format parser func. Indices are lower case.
func (l *Parser) RegisterParser(format string, parser ParserFunc) {
l.parsers[format] = parser
}
// ReadStruct reads from given file, parsing into structure
func (l *Parser) ReadStruct(filename, format string) (interface{}, error) {
f, err := os.Open(filename)
if err != nil {
slog.Infof("Can't open file %s", filename)
return nil, err
}
defer f.Close()
return l.ParseStruct(f, format)
}
// ParseStruct parses byte slice into map or slice
func (l *Parser) ParseStruct(content io.Reader, format string) (interface{}, error) {
var out interface{}
var err error
if parser, ok := l.parsers[format]; ok {
out, err = parser(content)
} else {
return nil, errors.New("Unknown file")
}
if err != nil {
return nil, fmt.Errorf("Can't parse %s: %v", format, err)
}
return out, nil
}