186 lines
4.0 KiB
Go
186 lines
4.0 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 := ""
|
|
if len(parseResult.Array()) > 0 {
|
|
for _, item := range parseResult.Array() {
|
|
if len(dataType) == 0 {
|
|
dataType = jg.getDataType(item)
|
|
continue
|
|
}
|
|
currentType := jg.getDataType(item)
|
|
if currentType != dataType {
|
|
if (dataType == "int64" && currentType == "float64") || (dataType == "float64" && currentType == "int64") {
|
|
dataType = "float64"
|
|
continue
|
|
}
|
|
// 不是所有数据类型都一致
|
|
if len(key) == 0 {
|
|
jg.result += "interface{}"
|
|
return
|
|
}
|
|
jg.append(jg.buildField("[]interface{}", key))
|
|
return
|
|
}
|
|
}
|
|
} else {
|
|
dataType = "interface{}"
|
|
}
|
|
// 对象,重新
|
|
if dataType == "object" {
|
|
instance := NewJSON2GO("")
|
|
r, _ := instance.Parse(parseResult.Array()[0].String())
|
|
dataType = strings.Replace(strings.Replace(r, "type", "", 1), "Automatic", "", 1)
|
|
}
|
|
|
|
// 所有数据类型都一致
|
|
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
|
|
}
|