// 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 }