json_filter/tree/generate.go

320 lines
7.1 KiB
Go
Raw Permalink Normal View History

2023-03-28 18:58:39 +08:00
// Package tree ...
//
// Description : tree ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2023-03-28 18:42
package tree
2023-03-29 14:40:59 +08:00
import (
2023-03-29 22:06:28 +08:00
"fmt"
2024-09-23 15:59:09 +08:00
"git.zhangdeman.cn/zhangdeman/wrapper"
2023-03-29 14:40:59 +08:00
"strings"
2023-03-29 22:06:28 +08:00
"github.com/pkg/errors"
2023-03-29 14:40:59 +08:00
)
2023-03-28 23:56:13 +08:00
2023-03-28 18:58:39 +08:00
// New 生成一棵JSON树
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 18:42 2023/3/28
2023-03-29 22:06:28 +08:00
func New(jsonData string) (*Generate, error) {
2023-03-28 23:56:13 +08:00
jsonData = strings.TrimSpace(jsonData)
g := &Generate{
2023-03-29 14:40:59 +08:00
jsonData: jsonData,
jsonDataByte: []byte(jsonData),
2023-03-28 23:56:13 +08:00
}
2023-03-29 14:40:59 +08:00
g.root = NewVirtualNode()
g.currentNode = g.root
2023-03-30 16:28:10 +08:00
g.currentParentNode = g.root
2023-03-29 22:06:28 +08:00
err := g.init()
return g, err
2023-03-28 23:56:13 +08:00
}
// Generate ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 22:46 2023/3/28
type Generate struct {
2023-03-29 22:06:28 +08:00
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
2023-03-30 12:26:17 +08:00
jsonValue string
2023-03-29 22:06:28 +08:00
)
// 获取类型
if valueType, startIndex, err = g.getValueType(startIndex); nil != err {
return err
}
g.root.ValueType = valueType
2023-03-30 14:32:35 +08:00
g.currentNode.ValueType = valueType
2023-03-29 22:06:28 +08:00
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
}
2023-03-30 12:26:17 +08:00
// 获取值
if jsonValue, startIndex, err = g.getValue(startIndex); nil != err {
2023-03-30 12:26:17 +08:00
return err
}
fmt.Println(jsonKey, valueType, jsonValue, startIndex)
2023-03-30 14:32:35 +08:00
// 创建节点, 并挂在到树上
var newNode *Node
2024-09-23 15:59:09 +08:00
if wrapper.ArrayType([]string{ValueTypeArray, ValueTypeMap}).Has(g.currentNode.ValueType) >= 0 {
2023-03-30 14:32:35 +08:00
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
2023-03-29 22:06:28 +08:00
}
return nil
2023-03-29 14:40:59 +08:00
}
// getKey 获取jsonKey TODO : 转义符识别
//
// Author : zhangdeman001@ke.com<张德满>
//
// Date : 11:36 2023/3/29
func (g *Generate) getKey(startIndex int) (string, int, error) {
2023-03-30 16:28:10 +08:00
keyCharList := make([]string, 0)
2023-03-29 14:40:59 +08:00
hasStart := false
for startIndex < len(g.jsonDataByte) {
charStr := string(g.jsonDataByte[startIndex])
2023-03-30 16:28:10 +08:00
if charStr == KeywordSpace && !hasStart {
2023-03-29 14:40:59 +08:00
// 跳过空格
2023-03-29 22:06:28 +08:00
startIndex++
2023-03-29 14:40:59 +08:00
continue
}
2024-09-23 15:59:09 +08:00
if charStr == KeywordDoubleQuote {
if !hasStart {
// 第一次遇见双引号
startIndex++
hasStart = true
continue
} else {
// 第二次遇见双引号key探寻结束
startIndex++
break
}
2023-03-29 14:40:59 +08:00
}
2023-03-30 12:02:40 +08:00
if !hasStart {
2024-09-23 15:59:09 +08:00
if wrapper.ArrayType([]string{
2023-03-30 16:28:10 +08:00
KeywordDoubleQuote,
KeywordObjectStart,
KeywordArrayStart,
KeywordComma,
2024-09-23 15:59:09 +08:00
}).Has(charStr) >= 0 {
startIndex++
continue
}
return "", startIndex, errors.New("parse key : format is invalid")
}
2023-03-30 12:02:40 +08:00
if charStr == KeywordEscapeSymbol {
// 转义符
startIndex++
if startIndex >= len(g.jsonDataByte) {
// 转义符后面没东西了
return "", startIndex, errors.New("escape symbol without any data")
}
charStr = string(g.jsonDataByte[startIndex])
}
2023-03-29 14:40:59 +08:00
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) {
2023-03-29 22:06:28 +08:00
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")
}
2023-03-29 14:40:59 +08:00
// 指针向后, 探寻到冒号之后第一个非空格字符串
hasFindColon := false
for startIndex < len(g.jsonDataByte) {
charStr := string(g.jsonDataByte[startIndex])
2024-09-23 15:59:09 +08:00
if charStr == KeywordSpace {
// 跳过空格
startIndex++
continue
} else {
// 非空格
if charStr != KeywordColon {
return "", startIndex, errors.New("value is invalid")
2023-03-29 14:40:59 +08:00
}
2024-09-23 15:59:09 +08:00
startIndex++
hasFindColon = true
break
2023-03-29 14:40:59 +08:00
}
}
if !hasFindColon {
2023-03-29 22:06:28 +08:00
return "", startIndex, errors.New("check json value type : value is invalid")
2023-03-29 14:40:59 +08:00
}
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:
2023-03-29 22:06:28 +08:00
return "", startIndex, errors.New("validate json value type : value type is invalid")
2023-03-29 14:40:59 +08:00
}
break
}
return keyValType, startIndex, nil
2023-03-28 23:56:13 +08:00
}
2023-03-30 12:26:17 +08:00
// getValue 获取JSON值
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 12:09 2023/3/30
func (g *Generate) getValue(startIndex int) (string, int, error) {
2023-03-30 12:26:17 +08:00
valArr := make([]string, 0)
isStart := false
for startIndex < len(g.jsonDataByte) {
str := string(g.jsonDataByte[startIndex])
2023-03-30 16:28:10 +08:00
if str == KeywordSpace && !isStart {
2023-03-30 12:26:17 +08:00
startIndex++
continue
}
if !isStart {
2024-09-23 15:59:09 +08:00
if wrapper.ArrayType([]string{KeywordArrayEnd, KeywordObjectEnd, KeywordComma}).Has(str) >= 0 {
2023-03-30 12:26:17 +08:00
startIndex++
continue
}
}
if isStart {
2024-09-23 15:59:09 +08:00
if wrapper.ArrayType([]string{KeywordDoubleQuote, KeywordArrayEnd, KeywordObjectEnd, KeywordComma}).Has(str) >= 0 {
2023-03-30 12:26:17 +08:00
// 值的拼接已结束
startIndex++
break
}
}
if str == KeywordDoubleQuote {
if isStart {
startIndex++
break
} else {
startIndex++
2023-03-30 16:28:10 +08:00
isStart = true
2023-03-30 12:26:17 +08:00
continue
}
}
isStart = true
2023-03-30 14:13:09 +08:00
if str == KeywordEscapeSymbol {
// 转义符
startIndex++
if startIndex >= len(g.jsonDataByte) {
// 转义符后面没东西了
return "", startIndex, errors.New("escape symbol without any data")
}
str = string(g.jsonDataByte[startIndex])
}
2023-03-30 12:26:17 +08:00
valArr = append(valArr, str)
startIndex++
}
return strings.Join(valArr, ""), startIndex, nil
2023-03-30 12:26:17 +08:00
}
2023-03-28 23:56:13 +08:00
// 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)
2023-03-28 18:58:39 +08:00
}