gopkg/tool/json2go/parser.go

170 lines
3.5 KiB
Go

// Package json2go ...
//
// Description : json2go ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-11-09 3:44 下午
package json2go
import (
"fmt"
"strings"
"git.zhangdeman.cn/zhangdeman/gopkg/util"
"github.com/pkg/errors"
"github.com/tidwall/gjson"
)
var (
// structName 结构体名称
structName = "Automatic"
)
// NewJSON2GO ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 6:13 下午 2021/11/9
func NewJSON2GO(name string) *JSON2GO {
if len(name) == 0 {
name = structName
}
return &JSON2GO{
structName: name,
}
}
// JSON2GO ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 6:12 下午 2021/11/9
type JSON2GO struct {
structName string
result string
}
// Parse ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 3:44 下午 2021/11/9
func (jg *JSON2GO) Parse(inputJSON string) (string, error) {
if !gjson.Valid(inputJSON) {
return "", errors.New("input json is invalid")
}
parseResult := gjson.Parse(inputJSON)
if parseResult.IsArray() {
jg.append("type " + jg.structName + " [] \n")
jg.parseArray("", parseResult)
} else {
jg.append("type " + jg.structName + " struct { \n")
jg.parseObject("", parseResult)
}
jg.append("}")
return jg.result, nil
}
// parseArray 解析array
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:37 下午 2021/11/9
func (jg *JSON2GO) parseArray(key string, parseResult gjson.Result) {
// 先遍历一遍确认所有数据类型都相同
dataType := ""
for _, item := range parseResult.Array() {
if len(dataType) == 0 {
dataType = jg.getDataType(item)
continue
}
if jg.getDataType(item) != dataType {
// 不是所有数据类型都一致
if len(key) == 0 {
jg.result += "interface{}"
return
}
jg.append(jg.buildField("[]interface{}", key))
return
}
}
// 所有数据类型都一致
if len(key) == 0 {
jg.append("[]" + dataType)
} else {
jg.append(jg.buildField("[]"+dataType, key))
}
}
// parseObject 解析object
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:37 下午 2021/11/9
func (jg *JSON2GO) parseObject(key string, parseResult gjson.Result) string {
if len(key) > 0 {
jg.result += util.SnakeCaseToCamel(key) + " struct { \n"
}
for k, v := range parseResult.Map() {
if v.IsObject() {
jg.parseObject(k, v)
} else if v.IsArray() {
jg.parseArray(k, v)
} else {
jg.append(jg.buildField(jg.getDataType(v), k))
}
}
if len(key) > 0 {
jg.append(" } `json:\"" + key + "\"`\n")
}
return ""
}
// getDataType 获取数据类型
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:14 下午 2021/11/9
func (jg *JSON2GO) getDataType(val gjson.Result) string {
switch val.Type {
case gjson.True:
fallthrough
case gjson.False:
return "bool"
case gjson.Null:
return "map[string]interface{}"
case gjson.String:
return "string"
case gjson.Number:
tmpVal := fmt.Sprintf("%v", val.Num)
if strings.Contains(tmpVal, ".") {
return "float64"
}
return "int64"
case gjson.JSON:
return "object"
default:
return "interface{}"
}
}
// buildField 构建字段
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 9:20 下午 2021/11/9
func (jq *JSON2GO) buildField(fieldType string, jsonTag string) string {
return util.SnakeCaseToCamel(jsonTag) + " " + fieldType + " `json:\"" + jsonTag + "\"`\n"
}
// append 构建result
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 9:19 下午 2021/11/9
func (jq *JSON2GO) append(appendStr string) {
jq.result += appendStr
}