Skip to content

Commit 50407a9

Browse files
authored
新增option.WithTagNameFromKey (#2)
1 parent b7d7eb0 commit 50407a9

File tree

11 files changed

+91
-16
lines changed

11 files changed

+91
-16
lines changed

Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
test:
2+
go test ./...

README.md

+19-2
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ type F struct {
212212
```
213213

214214
## 二、各种配置项函数用法
215-
### 2.1 option.WithSpecifyType 指定生成类型
215+
### 2.1 option.WithSpecifyType 指定生成类型(支持json/yaml)
216216
```go
217217
obj := `
218218
{
@@ -240,9 +240,26 @@ type reqName struct {
240240
Count int `json:"count"`
241241
Data map[string]string `json:"data"`
242242
Duration int `json:"duration"`
243-
entities interface{} `json:"json:entities"`
243+
Entities interface{} `json:"entities"`
244244
Timestamp int `json:"timestamp"`
245245
URI string `json:"uri"`
246246
}
247247

248+
```
249+
### 2.2 option.WithTagNameFromKey tag直接使用key的名字(支持http header)
250+
http header比较特殊,传递的标准header头会有-符。可以使用option.WithTagNameFromKey()指定直接使用key的名字当作tag名(header:"xxx")这里的xxx
251+
```go
252+
h := http.Header{
253+
"Content-Type": []string{"application/json"},
254+
"Accept": []string{"application/json"},
255+
}
256+
257+
res, err := http.Marshal(h, option.WithStructName("test"), option.WithTagNameFromKey())
258+
259+
// output res
260+
type test struct {
261+
Accept string `header:"Accept"`
262+
ContentType string `header:"Content-Type"`
263+
}
264+
248265
```

header/header_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
package header
44

55
import (
6+
"bytes"
67
"fmt"
78
"go/format"
89
"net/http"
10+
"os"
911
"testing"
1012

1113
"github.com/antlabs/tostruct/option"
@@ -44,3 +46,40 @@ func TestHead2struct(t *testing.T) {
4446

4547
}
4648
}
49+
50+
func TestHead2struct2(t *testing.T) {
51+
for _, tc := range [][]string{
52+
{"Content-Type", "application/json", "Accept", "application/json"},
53+
} {
54+
h := make(http.Header)
55+
for i := 0; i < len(tc); i += 2 {
56+
h.Set(tc[i], tc[i+1])
57+
}
58+
59+
res, err := Marshal(h, option.WithStructName("test"), option.WithTagNameFromKey())
60+
assert.NoError(t, err)
61+
62+
all, err := os.ReadFile("../testdata/testheader.0.txt")
63+
assert.NoError(t, err)
64+
assert.Equal(t, string(bytes.TrimSpace(all)), string(res))
65+
66+
}
67+
}
68+
69+
func TestHead2struct3(t *testing.T) {
70+
for _, h := range []http.Header{
71+
{
72+
"Content-Type": []string{"application/json"},
73+
"Accept": []string{"application/json"},
74+
},
75+
} {
76+
77+
res, err := Marshal(h, option.WithStructName("test"), option.WithTagNameFromKey())
78+
assert.NoError(t, err)
79+
80+
all, err := os.ReadFile("../testdata/testheader.0.txt")
81+
assert.NoError(t, err)
82+
assert.Equal(t, string(bytes.TrimSpace(all)), string(res))
83+
84+
}
85+
}

internal/map2struct/map2struct.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"sort"
1010

1111
"github.com/antlabs/tostruct/internal/guesstype"
12-
"github.com/antlabs/tostruct/internal/name"
12+
"github.com/antlabs/tostruct/name"
1313
"github.com/antlabs/tostruct/option"
1414
)
1515

@@ -30,6 +30,10 @@ func MapGenStruct(m map[string][]string, opt option.Option) (res []byte, err err
3030
for _, k := range ks {
3131
v := m[k]
3232
fieldName, tagName := name.GetFieldAndTagName(k)
33+
if opt.TagNameFromKey {
34+
tagName = k
35+
}
36+
3337
tagStr := fmt.Sprintf("`%s:%q`", tag, tagName)
3438
if len(v) == 0 {
3539
fmt.Fprintf(&out, "%s string %s\n", fieldName, tagStr)

json/json.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import (
1111
"strings"
1212

1313
"github.com/antlabs/gstl/mapex"
14-
"github.com/antlabs/tostruct/internal/name"
1514
"github.com/antlabs/tostruct/internal/tab"
15+
"github.com/antlabs/tostruct/name"
1616
"github.com/antlabs/tostruct/option"
1717
)
1818

@@ -254,10 +254,6 @@ func (f *JSON) marshalMap(key string, m map[string]interface{}, typePrefix strin
254254
}
255255

256256
func (f *JSON) marshalArray(key string, a []interface{}, depth int, buf *bytes.Buffer, keyPath string) {
257-
if len(a) == 0 {
258-
buf.WriteString(fmt.Sprintf("%s interface{} `json:\"json:%s\"`", key, key))
259-
return
260-
}
261257

262258
f.marshalValue(key, a[0], true, depth, buf, keyPath)
263259
}
@@ -287,6 +283,10 @@ func (f *JSON) marshalValue(key string, obj interface{}, fromArray bool, depth i
287283
case map[string]interface{}:
288284
f.marshalMap(key, v, typePrefix, depth, buf, keyPath)
289285
case []interface{}:
286+
if len(v) == 0 {
287+
buf.WriteString(fmt.Sprintf("%s interface{} `json:\"%s\"`", fieldName, key))
288+
return
289+
}
290290
f.marshalArray(key, v, depth, buf, keyPath+"[0]")
291291
case string:
292292
buf.WriteString(fmt.Sprintf(stringFmt, fieldName, typePrefix, f.Tag, tagName))
File renamed without changes.

option/option.go

+14-5
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ package option
55
type OptionFunc func(c *Option)
66

77
type Option struct {
8-
Inline bool
9-
Tag string
10-
StructName string
11-
TypeMap map[string]string
8+
Inline bool
9+
Tag string
10+
StructName string
11+
TypeMap map[string]string
12+
TagNameFromKey bool
1213
}
1314

1415
// 控制生成的结构体是否内联
@@ -56,9 +57,17 @@ func WithStructName(name string) OptionFunc {
5657
// ".data": "map[string]string"
5758
// })
5859
//
59-
// 目录只支持json/yaml
60+
// 目前只支持json/yaml
6061
func WithSpecifyType(typeMap map[string]string) OptionFunc {
6162
return func(c *Option) {
6263
c.TypeMap = typeMap
6364
}
6465
}
66+
67+
// tag使用变量名, http header特殊一点
68+
// 目前仅仅支持http header marshal
69+
func WithTagNameFromKey() OptionFunc {
70+
return func(c *Option) {
71+
c.TagNameFromKey = true
72+
}
73+
}

testdata/testheader.0.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
type test struct {
2+
Accept string `header:"Accept"`
3+
ContentType string `header:"Content-Type"`
4+
}

testdata/testjson7.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ type reqName struct {
33
Count int `json:"count"`
44
Data map[string]string `json:"data"`
55
Duration int `json:"duration"`
6-
entities interface{} `json:"json:entities"`
6+
Entities interface{} `json:"entities"`
77
Timestamp int `json:"timestamp"`
88
URI string `json:"uri"`
99
}

testdata/testjson8.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ type reqName struct {
55
Data map[string]string `json:"data"`
66
} `json:"data"`
77
Duration int `json:"duration"`
8-
entities interface{} `json:"json:entities"`
8+
Entities interface{} `json:"entities"`
99
Timestamp int `json:"timestamp"`
1010
URI string `json:"uri"`
1111
}

testdata/testjson8.1.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ type reqName struct {
33
Count int `json:"count"`
44
Data Data `json:"data"`
55
Duration int `json:"duration"`
6-
entities interface{} `json:"json:entities"`
6+
Entities interface{} `json:"entities"`
77
Timestamp int `json:"timestamp"`
88
URI string `json:"uri"`
99
}

0 commit comments

Comments
 (0)