Skip to content

Commit b5662bf

Browse files
committed
fix: list more than 1 item
1 parent 0a286b9 commit b5662bf

File tree

5 files changed

+145
-119
lines changed

5 files changed

+145
-119
lines changed

bin/xlsxcfg/root_cmd.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ func run(cmd *cobra.Command, args []string) {
4646
if err != nil {
4747
log.Fatalln("load proto files failed:", err)
4848
}
49-
sheetsData, err := xlsxcfg.LoadXlsxFiles(ctx, xlsxcfg.NewParameter(cfg, typeProvider), args...)
49+
sheetsData, err := xlsxcfg.LoadXlsxFiles(ctx, xlsxcfg.NewConfig(cfg, typeProvider), args...)
5050
if err != nil {
51-
log.Fatalln("parse xls files failed:", err)
51+
log.Fatalln("parse xlsx files failed:", err)
5252
}
5353

5454
msgFactory := dynamic.NewMessageFactoryWithDefaults()
@@ -77,7 +77,7 @@ func run(cmd *cobra.Command, args []string) {
7777
}
7878
}
7979

80-
func writeFile(cfg *xlsxcfg.Config, sheet string, msg protoiface.MessageV1, jm *jsonpb.Marshaler) {
80+
func writeFile(cfg *xlsxcfg.ConfigFile, sheet string, msg protoiface.MessageV1, jm *jsonpb.Marshaler) {
8181
if cfg.Output.WriteBytes {
8282
// output proto bytes file
8383
buf, err := proto.Marshal(msg)

config.go

+15-15
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"gopkg.in/yaml.v3"
99
)
1010

11-
type Config struct {
11+
type ConfigFile struct {
1212
Proto struct {
1313
Files []string `yaml:"files"`
1414
ImportPath []string `yaml:"import_path"`
@@ -29,8 +29,8 @@ type Config struct {
2929
} `yaml:"output"`
3030
}
3131

32-
func ConfigFromFile(f string) (*Config, error) {
33-
c := &Config{}
32+
func ConfigFromFile(f string) (*ConfigFile, error) {
33+
c := &ConfigFile{}
3434
if bs, err := os.ReadFile(f); err != nil {
3535
return nil, err
3636
} else if err = yaml.Unmarshal(bs, c); err != nil {
@@ -39,19 +39,19 @@ func ConfigFromFile(f string) (*Config, error) {
3939
return c, nil
4040
}
4141

42-
type Parameter struct {
43-
*Config
42+
type Config struct {
43+
*ConfigFile
4444
tp TypeProvidor
4545
}
4646

47-
func NewParameter(cfg *Config, tp TypeProvidor) *Parameter {
48-
return &Parameter{
49-
Config: cfg,
50-
tp: tp,
47+
func NewConfig(cfg *ConfigFile, tp TypeProvidor) *Config {
48+
return &Config{
49+
ConfigFile: cfg,
50+
tp: tp,
5151
}
5252
}
5353

54-
func (p *Parameter) IsStrField(typeName, fieldPath string) bool {
54+
func (p *Config) IsStrField(typeName, fieldPath string) bool {
5555
md := p.tp.MessageByName(typeName)
5656
if md == nil {
5757
log.Println("message " + typeName + " cannot find in proto messages")
@@ -60,19 +60,19 @@ func (p *Parameter) IsStrField(typeName, fieldPath string) bool {
6060
return IsStrField(md, strings.Split(fieldPath, ".")...)
6161
}
6262

63-
func (p *Parameter) IsComment(i int, row []string) bool {
64-
for _, l := range p.Config.Sheet.CommentRows {
63+
func (p *Config) IsComment(i int, row []string) bool {
64+
for _, l := range p.ConfigFile.Sheet.CommentRows {
6565
if l == i+1 {
6666
return true
6767
}
6868
}
6969
return false
7070
}
7171

72-
func (p *Parameter) IsMeta(i int, row []string) bool {
73-
return i+1 == p.Config.Sheet.MetaRow
72+
func (p *Config) IsMeta(i int, row []string) bool {
73+
return i+1 == p.ConfigFile.Sheet.MetaRow
7474
}
7575

76-
func (p *Parameter) IsData(i int, row []string) bool {
76+
func (p *Config) IsData(i int, row []string) bool {
7777
return i+1 >= p.Sheet.DataRowStart
7878
}

xlsx_row_parser.go

+97-69
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,36 @@ import (
77
)
88

99
type rowParser struct {
10-
param *Parameter
10+
param *Config
1111
isStr func(fieldPath string) bool
1212
errStack []error
1313
hasMeta bool
1414

1515
res map[string]any
16-
fn []func(v string)
16+
set []func(v string)
1717
fnGet map[string]func() any
1818
fnSet map[string]func(v any)
1919
}
2020

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+
2130
// 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
2837
for _, meta := range row {
2938
if meta == "" {
30-
t.fn = append(t.fn, func(_ string) {})
39+
p.set = append(p.set, func(_ string) {})
3140
continue
3241
}
3342
tr := newTokenReader(meta)
@@ -38,113 +47,132 @@ func (t *rowParser) Meta(ctx context.Context, row []string) {
3847
typePath := tr.TypePath()
3948
// log.Printf("head: %s -- ident: %s -- prevIdent: %s -- fullIdent: %s -- typePath: %s\n", hd, ident, prevIdent, fullIdent, typePath)
4049
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())
4951
} else if tr.HasNext() {
50-
t.metaStruct(ident, prevIdent, fullIdent, typePath)
52+
p.metaStruct(ident, prevIdent, fullIdent, typePath)
5153
} else {
52-
t.metaField(ident, prevIdent, fullIdent, typePath)
54+
p.metaField(ident, prevIdent, fullIdent, typePath)
5355
}
5456
}
5557
}
56-
t.hasMeta = true
58+
p.hasMeta = true
5759
}
5860

5961
// 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 {
6264
return nil, fmt.Errorf("row parser no metadata")
6365
}
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]
6577
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)
6880
}
6981
}
70-
if len(t.errStack) > 0 {
71-
return nil, t.errStack[0]
82+
if len(p.errStack) > 0 {
83+
return nil, p.errStack[0]
7284
}
73-
return t.res, nil
85+
return p.res, nil
7486
}
7587

76-
func (t *rowParser) convertVal(typePath, fullIdent, v string) any {
88+
func (p *rowParser) convertVal(typePath, fullIdent, v string) any {
7789
var res any
78-
if t.isStr(typePath) {
90+
if p.isStr(typePath) {
7991
res = v
8092
} else {
93+
if v == "" {
94+
v = "0"
95+
}
8196
n, e := strconv.ParseInt(v, 10, 64)
8297
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))
8499
} else {
85100
res = n
86101
}
87102
}
88103
return res
89104
}
90105

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)
110117
}
111-
return arr
118+
p.fnGet[prevIdent]().(map[string]any)[ident] = list
112119
}
113-
t.fnGet[fullIdentList] = getList
120+
return list.([]any)[idx]
114121
}
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
118136
}
119-
t.fnSet[fullIdent] = func(v any) {
120-
arr := getList()
121-
arr.([]any)[ai] = v
137+
if !isEnd {
138+
return
122139
}
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+
})
123148
}
124149

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]
128153
}
129-
t.fnSet[fullIdent] = func(v any) {
130-
prev := t.fnGet[prevIdent]()
154+
p.fnSet[fullIdent] = func(v any) {
155+
prev := p.fnGet[prevIdent]()
131156
if prev == nil {
132157
prev = map[string]any{}
133-
t.fnSet[prevIdent](prev)
158+
p.fnSet[prevIdent](prev)
134159
}
135160
prev.(map[string]any)[ident] = v
136161
}
137162
}
138163

139-
func (t *rowParser) metaField(ident, prevIdent, fullIdent, typePath string) {
164+
func (p *rowParser) metaField(ident, prevIdent, fullIdent, typePath string) {
140165
// end at a field
141-
t.fn = append(t.fn, func(v string) {
166+
p.set = append(p.set, func(v string) {
142167
// 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]()
144172
if prev == nil {
145173
prev = map[string]any{}
146-
t.fnSet[prevIdent](prev)
174+
p.fnSet[prevIdent](prev)
147175
}
148-
prev.(map[string]any)[ident] = t.convertVal(typePath, fullIdent, v)
176+
prev.(map[string]any)[ident] = p.convertVal(typePath, fullIdent, v)
149177
})
150178
}

0 commit comments

Comments
 (0)