优化自动生成json #3
113
filter.go
113
filter.go
@ -10,14 +10,13 @@ package filter
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/wrapper"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
"github.com/tidwall/sjson"
|
"github.com/tidwall/sjson"
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"git.zhangdeman.cn/zhangdeman/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewFilter 过滤器实例
|
// NewFilter 过滤器实例
|
||||||
@ -64,17 +63,7 @@ func (f *filter) Deal() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
sourceResult := gjson.Get(f.sourceData, rule.SourcePath)
|
sourceResult := gjson.Get(f.sourceData, rule.SourcePath)
|
||||||
var (
|
if formatVal, err = f.getValue(rule.DataType, sourceResult, rule.DefaultValue); nil != err {
|
||||||
sourceVal string
|
|
||||||
)
|
|
||||||
|
|
||||||
if !sourceResult.Exists() {
|
|
||||||
// 不存在, 使用默认值
|
|
||||||
sourceVal = rule.DefaultValue
|
|
||||||
} else {
|
|
||||||
sourceVal = sourceResult.String()
|
|
||||||
}
|
|
||||||
if formatVal, err = f.getValue(rule.DataType, sourceVal); nil != err {
|
|
||||||
return fmt.Errorf("%s = %v can not convert to %s : %s", rule.SourcePath, sourceResult.Value(), rule.DataType, err.Error())
|
return fmt.Errorf("%s = %v can not convert to %s : %s", rule.SourcePath, sourceResult.Value(), rule.DataType, err.Error())
|
||||||
}
|
}
|
||||||
if f.formatResult, err = sjson.Set(f.formatResult, rule.MapPath, formatVal); nil != err {
|
if f.formatResult, err = sjson.Set(f.formatResult, rule.MapPath, formatVal); nil != err {
|
||||||
@ -183,56 +172,60 @@ func (f *filter) Parse(receiver interface{}) error {
|
|||||||
// Author : go_developer@163.com<白茶清欢>
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
//
|
//
|
||||||
// Date : 12:25 2022/7/4
|
// Date : 12:25 2022/7/4
|
||||||
func (f *filter) getValue(dataType string, defaultValue string) (interface{}, error) {
|
func (f *filter) getValue(dataType string, sourceValue gjson.Result, defaultValue string) (interface{}, error) {
|
||||||
|
sourceValueStr := defaultValue
|
||||||
|
if sourceValue.Exists() {
|
||||||
|
str := sourceValue.String()
|
||||||
|
if len(str) > 0 {
|
||||||
|
sourceValueStr = str
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strVal := wrapper.String(sourceValueStr)
|
||||||
|
|
||||||
switch dataType {
|
switch dataType {
|
||||||
case "int8":
|
case wrapper.DataTypeInt8:
|
||||||
|
return strVal.ToInt8()
|
||||||
|
case wrapper.DataTypeInt16:
|
||||||
|
return strVal.ToInt16()
|
||||||
|
case wrapper.DataTypeInt32:
|
||||||
|
return strVal.ToInt32()
|
||||||
|
case wrapper.DataTypeInt64:
|
||||||
|
return strVal.ToInt64()
|
||||||
|
case wrapper.DataTypeInt:
|
||||||
|
return strVal.ToInt()
|
||||||
|
case wrapper.DataTypeUint8:
|
||||||
|
return strVal.ToUint8()
|
||||||
|
case wrapper.DataTypeUint16:
|
||||||
|
return strVal.ToUint16()
|
||||||
|
case wrapper.DataTypeUint32:
|
||||||
|
return strVal.ToUint32()
|
||||||
|
case wrapper.DataTypeUint64:
|
||||||
|
return strVal.ToUint64()
|
||||||
|
case wrapper.DataTypeUint:
|
||||||
|
return strVal.ToUint()
|
||||||
|
case wrapper.DataTypeBool:
|
||||||
|
return strVal.ToBool()
|
||||||
|
case wrapper.DataTypeFloat32:
|
||||||
|
return strVal.ToFloat64()
|
||||||
|
case wrapper.DataTypeFloat64:
|
||||||
fallthrough
|
fallthrough
|
||||||
case "int16":
|
case wrapper.DataTypeFloat:
|
||||||
fallthrough
|
fallthrough
|
||||||
case "int32":
|
case wrapper.DataTypeDouble:
|
||||||
fallthrough
|
return strVal.ToFloat64()
|
||||||
case "int64":
|
case wrapper.DataTypeNumber:
|
||||||
fallthrough
|
return strVal.ToNumber()
|
||||||
case "int":
|
case wrapper.DataTypeString:
|
||||||
var (
|
return sourceValueStr, nil
|
||||||
err error
|
case wrapper.DataTypeAny:
|
||||||
val int64
|
return sourceValue.Value(), nil
|
||||||
)
|
case wrapper.DataTypeAnySlice:
|
||||||
err = util.ConvertAssign(&val, defaultValue)
|
// 任意类型的list
|
||||||
return val, err
|
return strVal.ToAnySlice()
|
||||||
case "uint8":
|
case wrapper.DataTypeObject:
|
||||||
fallthrough
|
// object
|
||||||
case "uint16":
|
return strVal.ToObject()
|
||||||
fallthrough
|
|
||||||
case "uint32":
|
|
||||||
fallthrough
|
|
||||||
case "uint64":
|
|
||||||
fallthrough
|
|
||||||
case "uint":
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
val uint64
|
|
||||||
)
|
|
||||||
err = util.ConvertAssign(&val, defaultValue)
|
|
||||||
return val, err
|
|
||||||
case "bool":
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
val bool
|
|
||||||
)
|
|
||||||
err = util.ConvertAssign(&val, defaultValue)
|
|
||||||
return val, err
|
|
||||||
case "float32":
|
|
||||||
fallthrough
|
|
||||||
case "float64":
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
val float64
|
|
||||||
)
|
|
||||||
err = util.ConvertAssign(&val, defaultValue)
|
|
||||||
return val, err
|
|
||||||
case "string":
|
|
||||||
return defaultValue, nil
|
|
||||||
default:
|
default:
|
||||||
return nil, errors.New(dataType + " is not support!")
|
return nil, errors.New(dataType + " is not support!")
|
||||||
}
|
}
|
||||||
|
7
go.mod
7
go.mod
@ -1,10 +1,10 @@
|
|||||||
module git.zhangdeman.cn/zhangdeman/json_filter
|
module git.zhangdeman.cn/zhangdeman/json_filter
|
||||||
|
|
||||||
go 1.17
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20220627070212-c590a0a1c216
|
git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20220627070212-c590a0a1c216
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230211164227-256094968151
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230505025924-96532aff0019
|
||||||
github.com/Jeffail/gabs v1.4.0
|
github.com/Jeffail/gabs v1.4.0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/smartystreets/goconvey v1.7.2
|
github.com/smartystreets/goconvey v1.7.2
|
||||||
@ -13,12 +13,15 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505080742-fa2f27724d76 // indirect
|
||||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||||
github.com/go-ini/ini v1.67.0 // indirect
|
github.com/go-ini/ini v1.67.0 // indirect
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
|
||||||
github.com/jtolds/gls v4.20.0+incompatible // indirect
|
github.com/jtolds/gls v4.20.0+incompatible // indirect
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
|
github.com/mssola/user_agent v0.6.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/smartystreets/assertions v1.2.0 // indirect
|
github.com/smartystreets/assertions v1.2.0 // indirect
|
||||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
|
16
go.sum
16
go.sum
@ -3,6 +3,18 @@ git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20220627070212-c590a0a1c216/go.mod
|
|||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20220626081130-cbac0b676fb8/go.mod h1:G2/OKMbEn89d+YUXQtv9Nlh0LGg14pOqDnbOgBTTRXY=
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20220626081130-cbac0b676fb8/go.mod h1:G2/OKMbEn89d+YUXQtv9Nlh0LGg14pOqDnbOgBTTRXY=
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230211164227-256094968151 h1:j537bRLQL1FlkdXTIaT9Ecjx5eogkPsGiTOWIEFQlc8=
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230211164227-256094968151 h1:j537bRLQL1FlkdXTIaT9Ecjx5eogkPsGiTOWIEFQlc8=
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230211164227-256094968151/go.mod h1:SyRTkOz6gxUVn3S/Qtkf+rhKV0I1ym8lwsT8YjggYFs=
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230211164227-256094968151/go.mod h1:SyRTkOz6gxUVn3S/Qtkf+rhKV0I1ym8lwsT8YjggYFs=
|
||||||
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230330065032-faba0a5a9ea1 h1:u2FdNfcGvRmlKpuPBk2qvYenkZjinHY2PLu5Wmhka8A=
|
||||||
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230330065032-faba0a5a9ea1/go.mod h1:SyRTkOz6gxUVn3S/Qtkf+rhKV0I1ym8lwsT8YjggYFs=
|
||||||
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230330082619-662152cb682d h1:kMQZmkYBceHM3O7wiCelSADjTyOF3EBxXTX8fgZA+6c=
|
||||||
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230330082619-662152cb682d/go.mod h1:qeVsrMae8ljqzcsmI+lWPU/4Rdjb9cOt4oaDUNEf1Ck=
|
||||||
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230505025924-96532aff0019 h1:eJ/9rEj2iI8P9I1DfCmMUvsV+n2EiAWCXnI9yVVDHO0=
|
||||||
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20230505025924-96532aff0019/go.mod h1:z2bP5LIwRVpWSQV0/a3WIFaoarJUP8kA/0Clv0bP+8I=
|
||||||
|
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505064614-5e785171ed67 h1:DH9K3fNddpFxRGLkcLP5MHsAQVinpWpmGzbVBf8yrKM=
|
||||||
|
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505064614-5e785171ed67/go.mod h1:2jc48WuVoHxZjkvlBewzp+ey8khP1K4OOcibVD1yL2k=
|
||||||
|
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505070245-b182b21e039b h1:ZwAA10/+v3FFAq5/EzjXdXDodmKppXb5gBkCcgaYVBo=
|
||||||
|
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505070245-b182b21e039b/go.mod h1:2jc48WuVoHxZjkvlBewzp+ey8khP1K4OOcibVD1yL2k=
|
||||||
|
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505080742-fa2f27724d76 h1:IEixZNZY3/nqb5v9PzzgSeXLPp0U7wRaxrM+ZaSh+j0=
|
||||||
|
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20230505080742-fa2f27724d76/go.mod h1:2jc48WuVoHxZjkvlBewzp+ey8khP1K4OOcibVD1yL2k=
|
||||||
github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo=
|
github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo=
|
||||||
github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
|
github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
|
||||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
|
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
|
||||||
@ -18,6 +30,10 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa
|
|||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
github.com/mssola/user_agent v0.6.0 h1:uwPR4rtWlCHRFyyP9u2KOV0u8iQXmS7Z7feTrstQwk4=
|
||||||
|
github.com/mssola/user_agent v0.6.0/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
3
tree/REDME.md
Normal file
3
tree/REDME.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# 说明
|
||||||
|
|
||||||
|
基于JSON数据生成数据树
|
73
tree/consts.go
Normal file
73
tree/consts.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Package tree ...
|
||||||
|
//
|
||||||
|
// Description : tree ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2023-03-28 18:32
|
||||||
|
package tree
|
||||||
|
|
||||||
|
const (
|
||||||
|
// KeywordObjectStart 对象开始标识
|
||||||
|
KeywordObjectStart = "{"
|
||||||
|
// KeywordObjectEnd 对象结束标识
|
||||||
|
KeywordObjectEnd = "}"
|
||||||
|
// KeywordArrayStart 数组开始标识
|
||||||
|
KeywordArrayStart = "["
|
||||||
|
// KeywordArrayEnd 数组结束标识
|
||||||
|
KeywordArrayEnd = "]"
|
||||||
|
// KeywordColon 冒号
|
||||||
|
KeywordColon = ":"
|
||||||
|
// KeywordComma 逗号
|
||||||
|
KeywordComma = ","
|
||||||
|
// KeywordDot .
|
||||||
|
KeywordDot = "."
|
||||||
|
// KeywordDoubleQuote 双引号
|
||||||
|
KeywordDoubleQuote = `"`
|
||||||
|
// KeywordEscapeSymbol 转义符号
|
||||||
|
KeywordEscapeSymbol = `\`
|
||||||
|
// KeywordSpace 空格
|
||||||
|
KeywordSpace = " "
|
||||||
|
// KeywordMinus 负号
|
||||||
|
KeywordMinus = "-"
|
||||||
|
// KeywordTrueStart true的起始值
|
||||||
|
KeywordTrueStart = "t"
|
||||||
|
// KeywordFalseStart false的起始值
|
||||||
|
KeywordFalseStart = "f"
|
||||||
|
KeywordZero = "0"
|
||||||
|
KeywordOne = "1"
|
||||||
|
KeywordTwo = "2"
|
||||||
|
KeywordThree = "3"
|
||||||
|
KeywordFour = "4"
|
||||||
|
KeywordFive = "5"
|
||||||
|
KeywordSix = "6"
|
||||||
|
KeywordSeven = "7"
|
||||||
|
KeywordEight = "8"
|
||||||
|
KeywordNine = "9"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ValueTypeString 字符串类型
|
||||||
|
ValueTypeString = "string"
|
||||||
|
// ValueTypeBool bool类型
|
||||||
|
ValueTypeBool = "bool"
|
||||||
|
// ValueTypeInteger int类型
|
||||||
|
ValueTypeInteger = "int64"
|
||||||
|
// ValueTypeFloat float类型
|
||||||
|
ValueTypeFloat = "float64"
|
||||||
|
// ValueTypeNumber 数字
|
||||||
|
ValueTypeNumber = "number"
|
||||||
|
// ValueTypeMap map数据
|
||||||
|
ValueTypeMap = "map"
|
||||||
|
// ValueTypeArray 数组
|
||||||
|
ValueTypeArray = "array"
|
||||||
|
)
|
||||||
|
|
||||||
|
// isBaseDataType 是否为基础数据类型
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 23:16 2023/3/28
|
||||||
|
func isBaseDataType(valueType string) bool {
|
||||||
|
return valueType != ValueTypeArray && valueType != ValueTypeMap
|
||||||
|
}
|
321
tree/generate.go
Normal file
321
tree/generate.go
Normal file
@ -0,0 +1,321 @@
|
|||||||
|
// Package tree ...
|
||||||
|
//
|
||||||
|
// Description : tree ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2023-03-28 18:42
|
||||||
|
package tree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/util"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// New 生成一棵JSON树
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 18:42 2023/3/28
|
||||||
|
func New(jsonData string) (*Generate, error) {
|
||||||
|
jsonData = strings.TrimSpace(jsonData)
|
||||||
|
g := &Generate{
|
||||||
|
jsonData: jsonData,
|
||||||
|
jsonDataByte: []byte(jsonData),
|
||||||
|
}
|
||||||
|
g.root = NewVirtualNode()
|
||||||
|
g.currentNode = g.root
|
||||||
|
g.currentParentNode = g.root
|
||||||
|
err := g.init()
|
||||||
|
return g, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 22:46 2023/3/28
|
||||||
|
type Generate struct {
|
||||||
|
root *Node // 根节点
|
||||||
|
currentNode *Node // 当前节点
|
||||||
|
currentParentNode *Node // 当前节点的父节点
|
||||||
|
jsonData string
|
||||||
|
jsonDataByte []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// init 初始化
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 21:23 2023/3/29
|
||||||
|
func (g *Generate) init() error {
|
||||||
|
startIndex := 0
|
||||||
|
var (
|
||||||
|
jsonKey string
|
||||||
|
err error
|
||||||
|
valueType string
|
||||||
|
jsonValue string
|
||||||
|
)
|
||||||
|
|
||||||
|
// 获取类型
|
||||||
|
if valueType, startIndex, err = g.getValueType(startIndex); nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
g.root.ValueType = valueType
|
||||||
|
g.currentNode.ValueType = valueType
|
||||||
|
|
||||||
|
for {
|
||||||
|
if startIndex >= len(g.jsonDataByte) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取字段
|
||||||
|
if jsonKey, startIndex, err = g.getKey(startIndex); nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// 获取类型
|
||||||
|
if valueType, startIndex, err = g.getValueType(startIndex); nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// 获取值
|
||||||
|
if jsonValue, startIndex, err = g.getValue(startIndex); nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(jsonKey, valueType, jsonValue, startIndex)
|
||||||
|
// 创建节点, 并挂在到树上
|
||||||
|
var newNode *Node
|
||||||
|
if util.Array.In(g.currentNode.ValueType, []string{ValueTypeArray, ValueTypeMap}) >= 0 {
|
||||||
|
newNode = NewNode(jsonKey, jsonValue, valueType, g.currentNode)
|
||||||
|
g.currentParentNode = g.currentNode
|
||||||
|
g.currentParentNode.SonNodeList = append(g.currentParentNode.SonNodeList, newNode)
|
||||||
|
} else {
|
||||||
|
newNode = NewNode(jsonKey, jsonValue, valueType, g.currentParentNode)
|
||||||
|
}
|
||||||
|
g.currentNode = newNode
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getKey 获取jsonKey TODO : 转义符识别
|
||||||
|
//
|
||||||
|
// Author : zhangdeman001@ke.com<张德满>
|
||||||
|
//
|
||||||
|
// Date : 11:36 2023/3/29
|
||||||
|
func (g *Generate) getKey(startIndex int) (string, int, error) {
|
||||||
|
keyCharList := make([]string, 0)
|
||||||
|
hasStart := false
|
||||||
|
for startIndex < len(g.jsonDataByte) {
|
||||||
|
charStr := string(g.jsonDataByte[startIndex])
|
||||||
|
if charStr == KeywordSpace && !hasStart {
|
||||||
|
// 跳过空格
|
||||||
|
startIndex++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if charStr == KeywordDoubleQuote && !hasStart {
|
||||||
|
// 第一次遇见双引号
|
||||||
|
startIndex++
|
||||||
|
hasStart = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if charStr == KeywordDoubleQuote && hasStart {
|
||||||
|
// 第二次遇见双引号,key探寻结束
|
||||||
|
startIndex++
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasStart {
|
||||||
|
if util.Array.In(charStr, []string{
|
||||||
|
KeywordDoubleQuote,
|
||||||
|
KeywordObjectStart,
|
||||||
|
KeywordArrayStart,
|
||||||
|
KeywordComma,
|
||||||
|
}) >= 0 {
|
||||||
|
startIndex++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return "", startIndex, errors.New("parse key : format is invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
if charStr == KeywordEscapeSymbol {
|
||||||
|
// 转义符
|
||||||
|
startIndex++
|
||||||
|
if startIndex >= len(g.jsonDataByte) {
|
||||||
|
// 转义符后面没东西了
|
||||||
|
return "", startIndex, errors.New("escape symbol without any data")
|
||||||
|
}
|
||||||
|
charStr = string(g.jsonDataByte[startIndex])
|
||||||
|
}
|
||||||
|
keyCharList = append(keyCharList, charStr)
|
||||||
|
startIndex++
|
||||||
|
}
|
||||||
|
jsonKey := strings.Join(keyCharList, "")
|
||||||
|
|
||||||
|
return jsonKey, startIndex, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getValueType 获取数据类型
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 14:37 2023/3/29
|
||||||
|
func (g *Generate) getValueType(startIndex int) (string, int, error) {
|
||||||
|
if startIndex == 0 {
|
||||||
|
// 初始对象特殊处理
|
||||||
|
if string(g.jsonDataByte[0]) == KeywordArrayStart {
|
||||||
|
return ValueTypeArray, 1, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始对象特殊处理
|
||||||
|
if string(g.jsonDataByte[0]) == KeywordObjectStart {
|
||||||
|
return ValueTypeMap, 1, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", 0, errors.New("root data parse : value is invalid")
|
||||||
|
}
|
||||||
|
// 指针向后, 探寻到冒号之后第一个非空格字符串
|
||||||
|
hasFindColon := false
|
||||||
|
for startIndex < len(g.jsonDataByte) {
|
||||||
|
charStr := string(g.jsonDataByte[startIndex])
|
||||||
|
if !hasFindColon {
|
||||||
|
if charStr == KeywordSpace {
|
||||||
|
// 跳过空格
|
||||||
|
startIndex++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if charStr != KeywordSpace {
|
||||||
|
// 非空格
|
||||||
|
if charStr != KeywordColon {
|
||||||
|
return "", startIndex, errors.New("value is invalid")
|
||||||
|
}
|
||||||
|
startIndex++
|
||||||
|
hasFindColon = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasFindColon {
|
||||||
|
return "", startIndex, errors.New("check json value type : value is invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
keyValType := ""
|
||||||
|
// 冒号后面探寻值的类型
|
||||||
|
for startIndex < len(g.jsonDataByte) {
|
||||||
|
charStr := string(g.jsonDataByte[startIndex])
|
||||||
|
if charStr == KeywordSpace {
|
||||||
|
// 跳过空格
|
||||||
|
startIndex++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非空
|
||||||
|
switch charStr {
|
||||||
|
case KeywordMinus:
|
||||||
|
fallthrough
|
||||||
|
case KeywordOne:
|
||||||
|
fallthrough
|
||||||
|
case KeywordTwo:
|
||||||
|
fallthrough
|
||||||
|
case KeywordThree:
|
||||||
|
fallthrough
|
||||||
|
case KeywordFour:
|
||||||
|
fallthrough
|
||||||
|
case KeywordFive:
|
||||||
|
fallthrough
|
||||||
|
case KeywordSix:
|
||||||
|
fallthrough
|
||||||
|
case KeywordSeven:
|
||||||
|
fallthrough
|
||||||
|
case KeywordEight:
|
||||||
|
fallthrough
|
||||||
|
case KeywordNine:
|
||||||
|
keyValType = ValueTypeNumber
|
||||||
|
case KeywordDoubleQuote:
|
||||||
|
keyValType = ValueTypeString
|
||||||
|
case KeywordArrayStart:
|
||||||
|
keyValType = ValueTypeArray
|
||||||
|
case KeywordObjectStart:
|
||||||
|
keyValType = ValueTypeMap
|
||||||
|
default:
|
||||||
|
return "", startIndex, errors.New("validate json value type : value type is invalid")
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return keyValType, startIndex, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getValue 获取JSON值
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 12:09 2023/3/30
|
||||||
|
func (g *Generate) getValue(startIndex int) (string, int, error) {
|
||||||
|
valArr := make([]string, 0)
|
||||||
|
isStart := false
|
||||||
|
for startIndex < len(g.jsonDataByte) {
|
||||||
|
str := string(g.jsonDataByte[startIndex])
|
||||||
|
if str == KeywordSpace && !isStart {
|
||||||
|
startIndex++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !isStart {
|
||||||
|
if util.Array.In(str, []string{KeywordArrayEnd, KeywordObjectEnd, KeywordComma}) >= 0 {
|
||||||
|
startIndex++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if isStart {
|
||||||
|
if util.Array.In(str, []string{KeywordDoubleQuote, KeywordArrayEnd, KeywordObjectEnd, KeywordComma}) >= 0 {
|
||||||
|
// 值的拼接已结束
|
||||||
|
startIndex++
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if str == KeywordDoubleQuote {
|
||||||
|
if isStart {
|
||||||
|
startIndex++
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
startIndex++
|
||||||
|
isStart = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isStart = true
|
||||||
|
if str == KeywordEscapeSymbol {
|
||||||
|
// 转义符
|
||||||
|
startIndex++
|
||||||
|
if startIndex >= len(g.jsonDataByte) {
|
||||||
|
// 转义符后面没东西了
|
||||||
|
return "", startIndex, errors.New("escape symbol without any data")
|
||||||
|
}
|
||||||
|
str = string(g.jsonDataByte[startIndex])
|
||||||
|
}
|
||||||
|
valArr = append(valArr, str)
|
||||||
|
startIndex++
|
||||||
|
}
|
||||||
|
return strings.Join(valArr, ""), startIndex, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// isObject 整体是否为对象
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 22:51 2023/3/28
|
||||||
|
func (g *Generate) isObject() bool {
|
||||||
|
return strings.HasPrefix(g.jsonData, KeywordObjectStart)
|
||||||
|
}
|
||||||
|
|
||||||
|
// isArray 整体是否为数组
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 22:51 2023/3/28
|
||||||
|
func (g *Generate) isArray() bool {
|
||||||
|
return strings.HasPrefix(g.jsonData, KeywordArrayStart)
|
||||||
|
}
|
23
tree/generate_test.go
Normal file
23
tree/generate_test.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Package tree ...
|
||||||
|
//
|
||||||
|
// Description : tree ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2023-03-29 21:32
|
||||||
|
package tree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNew(t *testing.T) {
|
||||||
|
jsonData := `{"name": "zhang", "age":17}`
|
||||||
|
g, err := New(jsonData)
|
||||||
|
if nil != err {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println(g)
|
||||||
|
}
|
108
tree/node.go
Normal file
108
tree/node.go
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
// Package tree ...
|
||||||
|
//
|
||||||
|
// Description : tree ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2023-03-28 18:12
|
||||||
|
package tree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.zhangdeman.cn/zhangdeman/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Node 节点的数据结构
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 18:12 2023/3/28
|
||||||
|
type Node struct {
|
||||||
|
IsVirtual bool // 是否虚拟节点, 主要应对输入的原始数据为list这一场景
|
||||||
|
Value interface{} // 节点的值
|
||||||
|
ValueType string // 数据类型 string / int64 / float64 / map / list / nil
|
||||||
|
Key string // 节点的key名称(输入的原始名称)
|
||||||
|
Show bool // 节点是否可见
|
||||||
|
ShowKey string // 重新序列化后, 对外输出的Key
|
||||||
|
AllowEdit bool // 当前key是否允许编辑
|
||||||
|
AllowChangeType bool // 在允许编辑的情况下, 是否允许修改数据类型
|
||||||
|
DefaultValue interface{} // 输入为value为nil时候的默认值
|
||||||
|
ParentNode *Node // 父节点
|
||||||
|
PreBrotherNode *Node // 前一个兄弟节点
|
||||||
|
LastBrotherNode *Node // 下一个兄弟节点
|
||||||
|
SonNodeList []*Node // 子节点列表
|
||||||
|
ObjectStack []string // 对象信息堆栈, 利用栈的括号匹配, 判断某一个对象是否扫面完成
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNode 创建新节点
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 23:02 2023/3/28
|
||||||
|
func NewNode(key string, value string, valueType string, parentNode *Node) *Node {
|
||||||
|
n := &Node{
|
||||||
|
IsVirtual: false,
|
||||||
|
Value: value,
|
||||||
|
ValueType: valueType,
|
||||||
|
Key: key,
|
||||||
|
Show: false,
|
||||||
|
ShowKey: "",
|
||||||
|
AllowEdit: false,
|
||||||
|
AllowChangeType: false,
|
||||||
|
DefaultValue: nil,
|
||||||
|
ParentNode: parentNode,
|
||||||
|
PreBrotherNode: nil,
|
||||||
|
LastBrotherNode: nil,
|
||||||
|
SonNodeList: nil,
|
||||||
|
ObjectStack: make([]string, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
switch valueType {
|
||||||
|
case ValueTypeString:
|
||||||
|
n.Value = value
|
||||||
|
case ValueTypeInteger:
|
||||||
|
var v int64
|
||||||
|
_ = util.ConvertAssign(&v, value)
|
||||||
|
n.Value = v
|
||||||
|
case ValueTypeFloat:
|
||||||
|
var v float64
|
||||||
|
_ = util.ConvertAssign(&v, value)
|
||||||
|
n.Value = v
|
||||||
|
case ValueTypeBool:
|
||||||
|
n.Value = strings.ToLower(value) == "true"
|
||||||
|
case ValueTypeMap:
|
||||||
|
n.Value = map[string]interface{}{}
|
||||||
|
n.SonNodeList = make([]*Node, 0)
|
||||||
|
case ValueTypeArray:
|
||||||
|
n.Value = []interface{}{}
|
||||||
|
n.SonNodeList = make([]*Node, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理 preBrother 和 lastBrother
|
||||||
|
if parentNode.ValueType == ValueTypeMap || parentNode.ValueType == ValueTypeArray {
|
||||||
|
// map 和 array 才有所谓的兄弟节点
|
||||||
|
if len(parentNode.SonNodeList) > 0 {
|
||||||
|
// 设置新节点的 pre 节点
|
||||||
|
n.PreBrotherNode = parentNode.SonNodeList[len(parentNode.SonNodeList)-1]
|
||||||
|
// 设置当前最后一个节点的 last 节点
|
||||||
|
parentNode.SonNodeList[len(parentNode.SonNodeList)-1].LastBrotherNode = n
|
||||||
|
}
|
||||||
|
// 新节点追加到子节点末尾
|
||||||
|
parentNode.SonNodeList = append(parentNode.SonNodeList, n)
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVirtualNode 创建一个新的虚拟节点
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 23:08 2023/3/28
|
||||||
|
func NewVirtualNode() *Node {
|
||||||
|
return &Node{
|
||||||
|
IsVirtual: true,
|
||||||
|
SonNodeList: make([]*Node, 0),
|
||||||
|
ObjectStack: make([]string, 0),
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user