-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathcfield.go
More file actions
133 lines (106 loc) · 2.61 KB
/
cfield.go
File metadata and controls
133 lines (106 loc) · 2.61 KB
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package csv
import (
"fmt"
"reflect"
"strconv"
)
type decoderFn func(*reflect.Value, *Row) error
// maps a CSV column Name and index to a StructField
type cfield struct {
colIndex int
structField *reflect.StructField
decoder decoderFn
}
func newCfield(index int, sf *reflect.StructField) cfield {
cf := cfield{
colIndex: index,
structField: sf,
}
cf.decoder = cf.unassignedDecoder
return cf
}
func (cf *cfield) assignUnmarshaller(code int) {
if code == impsPtr {
cf.decoder = cf.unmarshalPointer
} else {
cf.decoder = cf.unmarshalValue
}
}
func (cf *cfield) unmarshalPointer(cell *reflect.Value, row *Row) error {
val := row.At(cf.colIndex)
m := cell.Addr().Interface().(Unmarshaler)
err := m.UnmarshalCSV(val, row)
return err
}
func (cf *cfield) unmarshalValue(cell *reflect.Value, row *Row) error {
val := row.At(cf.colIndex)
m := cell.Interface().(Unmarshaler)
err := m.UnmarshalCSV(val, row)
return err
}
func (cf *cfield) assignDecoder() {
switch cf.structField.Type.Kind() {
case reflect.String:
cf.decoder = cf.decodeString
case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int8:
cf.decoder = cf.decodeInt
case reflect.Float32:
cf.decoder = cf.decodeFloat(32)
case reflect.Float64:
cf.decoder = cf.decodeFloat(64)
case reflect.Bool:
cf.decoder = cf.decodeBool
default:
cf.decoder = cf.ignoreValue
}
}
func (cf *cfield) decodeBool(cell *reflect.Value, row *Row) error {
val := row.At(cf.colIndex)
var bv bool
bt := cf.structField.Tag.Get("true")
bf := cf.structField.Tag.Get("false")
switch val {
case bt:
bv = true
case bf:
bv = false
default:
bv = true
}
cell.SetBool(bv)
return nil
}
func (cf *cfield) decodeInt(cell *reflect.Value, row *Row) error {
val := row.At(cf.colIndex)
i, e := strconv.Atoi(val)
if e != nil {
return e
}
cell.SetInt(int64(i))
return nil
}
func (cf *cfield) decodeString(cell *reflect.Value, row *Row) error {
val := row.At(cf.colIndex)
cell.SetString(val)
return nil
}
func (cf *cfield) decodeFloat(bit int) decoderFn {
return func(cell *reflect.Value, row *Row) error {
val := row.At(cf.colIndex)
n, err := strconv.ParseFloat(val, bit)
if err != nil {
return err
}
cell.SetFloat(n)
return nil
}
}
// ignoreValue does nothing. This is for unsupported types.
func (cf *cfield) ignoreValue(cell *reflect.Value, row *Row) error {
return nil
}
// unassignedDecoder is the default decoder. It returns an error since it should
// have been assigned.
func (cf *cfield) unassignedDecoder(cell *reflect.Value, row *Row) error {
return fmt.Errorf("no decoder for %v", cf.structField.Name)
}