@@ -7,27 +7,36 @@ import (
7
7
)
8
8
9
9
type rowParser struct {
10
- param * Parameter
10
+ param * Config
11
11
isStr func (fieldPath string ) bool
12
12
errStack []error
13
13
hasMeta bool
14
14
15
15
res map [string ]any
16
- fn []func (v string )
16
+ set []func (v string )
17
17
fnGet map [string ]func () any
18
18
fnSet map [string ]func (v any )
19
19
}
20
20
21
+ func newRowParser (typeName string , param * Config ) * rowParser {
22
+ return & rowParser {
23
+ param : param ,
24
+ isStr : func (fieldPath string ) bool {
25
+ return param .IsStrField (typeName , fieldPath )
26
+ },
27
+ }
28
+ }
29
+
21
30
// Meta feed metadata row to the parser.
22
- func (t * rowParser ) Meta (ctx context.Context , row []string ) {
23
- t .fnGet = make (map [string ]func () any , len (row ))
24
- t .fnSet = make (map [string ]func (v any ), len (row ))
25
- t . fn = make ([]func (v string ), 0 , len (row ))
26
- t .res = make (map [string ]any )
27
- t .fnGet ["" ] = func () any { return t .res } // top level getter
31
+ func (p * rowParser ) Meta (ctx context.Context , row []string ) {
32
+ p .fnGet = make (map [string ]func () any , len (row ))
33
+ p .fnSet = make (map [string ]func (v any ), len (row ))
34
+ p . set = make ([]func (v string ), 0 , len (row ))
35
+ p .res = make (map [string ]any )
36
+ p .fnGet ["" ] = func () any { return p .res } // top level getter
28
37
for _ , meta := range row {
29
38
if meta == "" {
30
- t . fn = append (t . fn , func (_ string ) {})
39
+ p . set = append (p . set , func (_ string ) {})
31
40
continue
32
41
}
33
42
tr := newTokenReader (meta )
@@ -38,113 +47,132 @@ func (t *rowParser) Meta(ctx context.Context, row []string) {
38
47
typePath := tr .TypePath ()
39
48
// log.Printf("head: %s -- ident: %s -- prevIdent: %s -- fullIdent: %s -- typePath: %s\n", hd, ident, prevIdent, fullIdent, typePath)
40
49
if ai := tr .ListIndex (); ai >= 0 {
41
- t .metaList (ident , prevIdent , fullIdent , typePath , ai - 1 )
42
- if ! tr .HasNext () {
43
- // end at list item
44
- t .fn = append (t .fn , func (v string ) {
45
- // log.Printf("arr set [%s] to [%s]\n", fullIdent, v)
46
- t.fnSet [fullIdent ](t .convertVal (typePath , fullIdent , v ))
47
- })
48
- }
50
+ p .metaList (ident , prevIdent , fullIdent , typePath , ai - 1 , ! tr .HasNext ())
49
51
} else if tr .HasNext () {
50
- t .metaStruct (ident , prevIdent , fullIdent , typePath )
52
+ p .metaStruct (ident , prevIdent , fullIdent , typePath )
51
53
} else {
52
- t .metaField (ident , prevIdent , fullIdent , typePath )
54
+ p .metaField (ident , prevIdent , fullIdent , typePath )
53
55
}
54
56
}
55
57
}
56
- t .hasMeta = true
58
+ p .hasMeta = true
57
59
}
58
60
59
61
// Parse parse one data row, MUST called after feed metadata.
60
- func (t * rowParser ) Parse (ctx context.Context , row []string ) (map [string ]any , error ) {
61
- if ! t .hasMeta {
62
+ func (p * rowParser ) Parse (ctx context.Context , row []string ) (map [string ]any , error ) {
63
+ if ! p .hasMeta {
62
64
return nil , fmt .Errorf ("row parser no metadata" )
63
65
}
64
- t .res = make (map [string ]any )
66
+ p .res = make (map [string ]any )
67
+ ni := len (row ) - 1
68
+ for ; ni >= 0 ; ni -- {
69
+ if row [ni ] != "" {
70
+ break
71
+ }
72
+ }
73
+ if ni < 0 {
74
+ return nil , nil
75
+ }
76
+ row = row [:ni + 1 ]
65
77
for i , cell := range row {
66
- if i < len (t . fn ) {
67
- t. fn [i ](cell )
78
+ if i < len (p . set ) {
79
+ p. set [i ](cell )
68
80
}
69
81
}
70
- if len (t .errStack ) > 0 {
71
- return nil , t .errStack [0 ]
82
+ if len (p .errStack ) > 0 {
83
+ return nil , p .errStack [0 ]
72
84
}
73
- return t .res , nil
85
+ return p .res , nil
74
86
}
75
87
76
- func (t * rowParser ) convertVal (typePath , fullIdent , v string ) any {
88
+ func (p * rowParser ) convertVal (typePath , fullIdent , v string ) any {
77
89
var res any
78
- if t .isStr (typePath ) {
90
+ if p .isStr (typePath ) {
79
91
res = v
80
92
} else {
93
+ if v == "" {
94
+ v = "0"
95
+ }
81
96
n , e := strconv .ParseInt (v , 10 , 64 )
82
97
if e != nil {
83
- t .errStack = append (t .errStack , fmt .Errorf ("parse col[%s] as number failed: %v" , fullIdent , e ))
98
+ p .errStack = append (p .errStack , fmt .Errorf ("parse col[%s] as number failed: %v" , fullIdent , e ))
84
99
} else {
85
100
res = n
86
101
}
87
102
}
88
103
return res
89
104
}
90
105
91
- func (t * rowParser ) metaList (ident , prevIdent , fullIdent , typePath string , ai int ) {
92
- fullIdentList := ident
93
- if prevIdent != "" {
94
- fullIdentList = prevIdent + "." + ident
95
- }
96
- getList := t .fnGet [fullIdentList ]
97
- if getList == nil {
98
- getList = func () any {
99
- arr := t .fnGet [prevIdent ]().(map [string ]any )[ident ]
100
- if arr == nil || len (arr .([]any )) <= ai {
101
- if arr != nil {
102
- oa := arr .([]any )
103
- na := make ([]any , ai + 1 )
104
- copy (na , oa )
105
- arr = na
106
- } else {
107
- arr = make ([]any , ai + 1 )
108
- }
109
- t .fnGet [prevIdent ]().(map [string ]any )[ident ] = arr
106
+ func (p * rowParser ) metaList (ident , prevIdent , fullIdent , typePath string , idx int , isEnd bool ) {
107
+ p .fnGet [fullIdent ] = func () any {
108
+ list := p .fnGet [prevIdent ]().(map [string ]any )[ident ]
109
+ if list == nil || len (list .([]any )) <= idx {
110
+ if list != nil {
111
+ oldList := list .([]any )
112
+ newList := make ([]any , idx + 1 )
113
+ copy (newList , oldList )
114
+ list = newList
115
+ } else {
116
+ list = make ([]any , idx + 1 )
110
117
}
111
- return arr
118
+ p . fnGet [ prevIdent ]().( map [ string ] any )[ ident ] = list
112
119
}
113
- t . fnGet [ fullIdentList ] = getList
120
+ return list .([] any )[ idx ]
114
121
}
115
- t .fnGet [fullIdent ] = func () any {
116
- arr := getList ()
117
- return arr .([]any )[ai ]
122
+ p .fnSet [fullIdent ] = func (v any ) {
123
+ list := p .fnGet [prevIdent ]().(map [string ]any )[ident ]
124
+ if list == nil || len (list .([]any )) <= idx {
125
+ if list != nil {
126
+ oldList := list .([]any )
127
+ newList := make ([]any , idx + 1 )
128
+ copy (newList , oldList )
129
+ list = newList
130
+ } else {
131
+ list = make ([]any , idx + 1 )
132
+ }
133
+ p .fnGet [prevIdent ]().(map [string ]any )[ident ] = list
134
+ }
135
+ list .([]any )[idx ] = v
118
136
}
119
- t .fnSet [fullIdent ] = func (v any ) {
120
- arr := getList ()
121
- arr .([]any )[ai ] = v
137
+ if ! isEnd {
138
+ return
122
139
}
140
+ // end at list item
141
+ p .set = append (p .set , func (v string ) {
142
+ // log.Printf("arr set [%s] to [%s]\n", fullIdent, v)
143
+ if v == "" {
144
+ return
145
+ }
146
+ p.fnSet [fullIdent ](p .convertVal (typePath , fullIdent , v ))
147
+ })
123
148
}
124
149
125
- func (t * rowParser ) metaStruct (ident , prevIdent , fullIdent , typePath string ) {
126
- t .fnGet [fullIdent ] = func () any {
127
- return t .fnGet [prevIdent ]().(map [string ]any )[ident ]
150
+ func (p * rowParser ) metaStruct (ident , prevIdent , fullIdent , typePath string ) {
151
+ p .fnGet [fullIdent ] = func () any {
152
+ return p .fnGet [prevIdent ]().(map [string ]any )[ident ]
128
153
}
129
- t .fnSet [fullIdent ] = func (v any ) {
130
- prev := t .fnGet [prevIdent ]()
154
+ p .fnSet [fullIdent ] = func (v any ) {
155
+ prev := p .fnGet [prevIdent ]()
131
156
if prev == nil {
132
157
prev = map [string ]any {}
133
- t .fnSet [prevIdent ](prev )
158
+ p .fnSet [prevIdent ](prev )
134
159
}
135
160
prev .(map [string ]any )[ident ] = v
136
161
}
137
162
}
138
163
139
- func (t * rowParser ) metaField (ident , prevIdent , fullIdent , typePath string ) {
164
+ func (p * rowParser ) metaField (ident , prevIdent , fullIdent , typePath string ) {
140
165
// end at a field
141
- t . fn = append (t . fn , func (v string ) {
166
+ p . set = append (p . set , func (v string ) {
142
167
// log.Printf("set [%s] to [%s]\n", fullIdent, v)
143
- prev := t .fnGet [prevIdent ]()
168
+ if v == "" {
169
+ return
170
+ }
171
+ prev := p .fnGet [prevIdent ]()
144
172
if prev == nil {
145
173
prev = map [string ]any {}
146
- t .fnSet [prevIdent ](prev )
174
+ p .fnSet [prevIdent ](prev )
147
175
}
148
- prev .(map [string ]any )[ident ] = t .convertVal (typePath , fullIdent , v )
176
+ prev .(map [string ]any )[ident ] = p .convertVal (typePath , fullIdent , v )
149
177
})
150
178
}
0 commit comments