Skip to content

Commit

Permalink
新增option.WithTagNameFromKey (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
guonaihong authored Jan 28, 2023
1 parent b7d7eb0 commit 50407a9
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 16 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
test:
go test ./...
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ type F struct {
```

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

```
### 2.2 option.WithTagNameFromKey tag直接使用key的名字(支持http header)
http header比较特殊,传递的标准header头会有-符。可以使用option.WithTagNameFromKey()指定直接使用key的名字当作tag名(header:"xxx")这里的xxx
```go
h := http.Header{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
}

res, err := http.Marshal(h, option.WithStructName("test"), option.WithTagNameFromKey())

// output res
type test struct {
Accept string `header:"Accept"`
ContentType string `header:"Content-Type"`
}

```
39 changes: 39 additions & 0 deletions header/header_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
package header

import (
"bytes"
"fmt"
"go/format"
"net/http"
"os"
"testing"

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

}
}

func TestHead2struct2(t *testing.T) {
for _, tc := range [][]string{
{"Content-Type", "application/json", "Accept", "application/json"},
} {
h := make(http.Header)
for i := 0; i < len(tc); i += 2 {
h.Set(tc[i], tc[i+1])
}

res, err := Marshal(h, option.WithStructName("test"), option.WithTagNameFromKey())
assert.NoError(t, err)

all, err := os.ReadFile("../testdata/testheader.0.txt")
assert.NoError(t, err)
assert.Equal(t, string(bytes.TrimSpace(all)), string(res))

}
}

func TestHead2struct3(t *testing.T) {
for _, h := range []http.Header{
{
"Content-Type": []string{"application/json"},
"Accept": []string{"application/json"},
},
} {

res, err := Marshal(h, option.WithStructName("test"), option.WithTagNameFromKey())
assert.NoError(t, err)

all, err := os.ReadFile("../testdata/testheader.0.txt")
assert.NoError(t, err)
assert.Equal(t, string(bytes.TrimSpace(all)), string(res))

}
}
6 changes: 5 additions & 1 deletion internal/map2struct/map2struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"sort"

"github.com/antlabs/tostruct/internal/guesstype"
"github.com/antlabs/tostruct/internal/name"
"github.com/antlabs/tostruct/name"
"github.com/antlabs/tostruct/option"
)

Expand All @@ -30,6 +30,10 @@ func MapGenStruct(m map[string][]string, opt option.Option) (res []byte, err err
for _, k := range ks {
v := m[k]
fieldName, tagName := name.GetFieldAndTagName(k)
if opt.TagNameFromKey {
tagName = k
}

tagStr := fmt.Sprintf("`%s:%q`", tag, tagName)
if len(v) == 0 {
fmt.Fprintf(&out, "%s string %s\n", fieldName, tagStr)
Expand Down
10 changes: 5 additions & 5 deletions json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"strings"

"github.com/antlabs/gstl/mapex"
"github.com/antlabs/tostruct/internal/name"
"github.com/antlabs/tostruct/internal/tab"
"github.com/antlabs/tostruct/name"
"github.com/antlabs/tostruct/option"
)

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

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

f.marshalValue(key, a[0], true, depth, buf, keyPath)
}
Expand Down Expand Up @@ -287,6 +283,10 @@ func (f *JSON) marshalValue(key string, obj interface{}, fromArray bool, depth i
case map[string]interface{}:
f.marshalMap(key, v, typePrefix, depth, buf, keyPath)
case []interface{}:
if len(v) == 0 {
buf.WriteString(fmt.Sprintf("%s interface{} `json:\"%s\"`", fieldName, key))
return
}
f.marshalArray(key, v, depth, buf, keyPath+"[0]")
case string:
buf.WriteString(fmt.Sprintf(stringFmt, fieldName, typePrefix, f.Tag, tagName))
Expand Down
File renamed without changes.
19 changes: 14 additions & 5 deletions option/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ package option
type OptionFunc func(c *Option)

type Option struct {
Inline bool
Tag string
StructName string
TypeMap map[string]string
Inline bool
Tag string
StructName string
TypeMap map[string]string
TagNameFromKey bool
}

// 控制生成的结构体是否内联
Expand Down Expand Up @@ -56,9 +57,17 @@ func WithStructName(name string) OptionFunc {
// ".data": "map[string]string"
// })
//
// 目录只支持json/yaml
// 目前只支持json/yaml
func WithSpecifyType(typeMap map[string]string) OptionFunc {
return func(c *Option) {
c.TypeMap = typeMap
}
}

// tag使用变量名, http header特殊一点
// 目前仅仅支持http header marshal
func WithTagNameFromKey() OptionFunc {
return func(c *Option) {
c.TagNameFromKey = true
}
}
4 changes: 4 additions & 0 deletions testdata/testheader.0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type test struct {
Accept string `header:"Accept"`
ContentType string `header:"Content-Type"`
}
2 changes: 1 addition & 1 deletion testdata/testjson7.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ type reqName struct {
Count int `json:"count"`
Data map[string]string `json:"data"`
Duration int `json:"duration"`
entities interface{} `json:"json:entities"`
Entities interface{} `json:"entities"`
Timestamp int `json:"timestamp"`
URI string `json:"uri"`
}
2 changes: 1 addition & 1 deletion testdata/testjson8.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ type reqName struct {
Data map[string]string `json:"data"`
} `json:"data"`
Duration int `json:"duration"`
entities interface{} `json:"json:entities"`
Entities interface{} `json:"entities"`
Timestamp int `json:"timestamp"`
URI string `json:"uri"`
}
2 changes: 1 addition & 1 deletion testdata/testjson8.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ type reqName struct {
Count int `json:"count"`
Data Data `json:"data"`
Duration int `json:"duration"`
entities interface{} `json:"json:entities"`
Entities interface{} `json:"entities"`
Timestamp int `json:"timestamp"`
URI string `json:"uri"`
}
Expand Down

0 comments on commit 50407a9

Please sign in to comment.