Skip to content

Commit f5a4b01

Browse files
committedJun 13, 2021
自定义json编解码器
1 parent 02e37dd commit f5a4b01

18 files changed

+466
-454
lines changed
 

‎errors.go ‎decode/errors.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,28 @@
1515
*
1616
*/
1717

18-
package json_diff
18+
package decode
1919

2020
import (
21-
`fmt`
22-
`github.com/pkg/errors`
21+
"fmt"
22+
"github.com/pkg/errors"
2323
)
2424

2525
// BadDiffsError 在输入不合法的 diffs 串时被返回
2626
var BadDiffsError = errors.New("diffs format error")
2727

2828
type JsonNodeError struct {
29-
Op string
29+
Op string
3030
}
3131

3232
func (e *JsonNodeError) Error() string {
33-
return fmt.Sprintf("fail to %s", e.Op)
33+
return fmt.Sprintf("fail to %s", e.Op)
3434
}
3535

3636
func GetJsonNodeError(op, msg string) error {
37-
return errors.Wrap(&JsonNodeError{Op: op}, msg)
37+
return errors.Wrap(&JsonNodeError{Op: op}, msg)
3838
}
3939

4040
func WrapJsonNodeError(op string, err error) error {
41-
return errors.Wrap(err, fmt.Sprintf("fail to %s", op))
42-
}
41+
return errors.Wrap(err, fmt.Sprintf("fail to %s", op))
42+
}

‎jsonnode.go ‎decode/jsonnode.go

+138-55
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,73 @@
1-
package json_diff
1+
/*
2+
* Copyright 2021 Junebao
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
package decode
219

320
import (
21+
"bytes"
422
"fmt"
23+
"regexp"
524
"strconv"
625
"strings"
726
)
827

28+
var keyReplaceRegexp = regexp.MustCompile(`~0*1`)
29+
30+
// KeyReplace 转义 key 中的特殊字符
31+
// "/" 会被替换成 "~1"
32+
// "~1" 会被替换成 "~01"
33+
// "~01" 会被替换为 "~001"
34+
// "~001" 会被替换为 "~0001"
35+
// 依此类推
36+
func KeyReplace(key string) string {
37+
resList := keyReplaceRegexp.FindAllStringIndex(key, -1)
38+
buff := bytes.NewBufferString("")
39+
pre := 0
40+
for _, res := range resList {
41+
buff.WriteString(key[pre:res[0]])
42+
buff.WriteRune('~')
43+
for i := 1; i < res[1]-res[0]; i++ {
44+
buff.WriteRune('0')
45+
}
46+
buff.WriteRune('1')
47+
pre = res[1]
48+
}
49+
buff.WriteString(key[pre:])
50+
return strings.ReplaceAll(buff.String(), "/", "~1")
51+
}
52+
53+
func KeyRestore(key string) string {
54+
key = strings.ReplaceAll(key, "~1", "/")
55+
resList := keyReplaceRegexp.FindAllStringIndex(key, -1)
56+
buff := bytes.NewBufferString("")
57+
pre := 0
58+
for _, res := range resList {
59+
buff.WriteString(key[pre:res[0]])
60+
buff.WriteRune('~')
61+
for i := 3; i < res[1]-res[0]; i++ {
62+
buff.WriteRune('0')
63+
}
64+
buff.WriteRune('1')
65+
pre = res[1]
66+
}
67+
buff.WriteString(key[pre:])
68+
return buff.String()
69+
}
70+
971
type JsonNodeType uint8
1072

1173
const (
@@ -23,15 +85,15 @@ const (
2385
)
2486

2587
func (jt JsonNodeType) String() string {
26-
switch jt {
27-
case JsonNodeTypeValue:
28-
return "value"
29-
case JsonNodeTypeSlice:
30-
return "slice"
31-
case JsonNodeTypeObject:
32-
return "object"
33-
}
34-
return ""
88+
switch jt {
89+
case JsonNodeTypeValue:
90+
return "value"
91+
case JsonNodeTypeSlice:
92+
return "slice"
93+
case JsonNodeTypeObject:
94+
return "object"
95+
}
96+
return ""
3597
}
3698

3799
// JsonNode 以树的形式组织 Json 中的每一项数据。
@@ -51,13 +113,23 @@ func (jt JsonNodeType) String() string {
51113
// 一个 Json 字节数组可以使用 Unmarshal 反序列化为 JsonNode 对象,
52114
// JsonNode 对象也可以使用 Marshal 序列化为 Json 字节数组
53115
type JsonNode struct {
54-
Type JsonNodeType `json:"type"`
55-
Hash string `json:"hash"`
56-
Key string `json:"key"`
57-
Value interface{} `json:"value"` // 保存 JsonNodeTypeValue 类型对象的值
58-
Children []*JsonNode `json:"children"` // 保存 JsonNodeTypeSlice 类型对象的值
59-
ChildrenMap map[string]*JsonNode `json:"children_map"` // 保存 JsonNodeTypeObject 类型对象的值
60-
Level int64 `json:"level"` // 该 node 所处的层级
116+
Type JsonNodeType `json:"type"`
117+
Hash string `json:"hash"`
118+
Key string `json:"key"`
119+
Value interface{} `json:"value"` // 保存 JsonNodeTypeValue 类型对象的值
120+
Children []*JsonNode `json:"children"` // 保存 JsonNodeTypeSlice 类型对象的值
121+
ChildrenMap map[string]*JsonNode `json:"children_map"` // 保存 JsonNodeTypeObject 类型对象的值
122+
Level int64 `json:"level"` // 该 node 所处的层级
123+
originalValue []byte // 保存反序列化时最原始的值,避免序列化动态类型转换
124+
}
125+
126+
func newOriginalValueNode(ov []byte, value interface{}, level int) *JsonNode {
127+
return &JsonNode{
128+
Type: JsonNodeTypeValue,
129+
Value: value,
130+
Level: int64(level),
131+
originalValue: ov,
132+
}
61133
}
62134

63135
func NewObjectNode(key string, childrenMap map[string]*JsonNode, level int) *JsonNode {
@@ -134,6 +206,17 @@ func (jn *JsonNode) ADD(key interface{}, value *JsonNode) error {
134206
return nil
135207
}
136208

209+
// Append 为当前 JsonNodeTypeSlice 节点追加子对象。
210+
// 只能用于 JsonNodeTypeSlice 类型的节点。
211+
func (jn *JsonNode) Append(v *JsonNode) error {
212+
if jn.Type != JsonNodeTypeSlice {
213+
return GetJsonNodeError("append",
214+
"cannot append an object to a node of type JsonNodeTypeSlice")
215+
}
216+
jn.Children = append(jn.Children, v)
217+
return nil
218+
}
219+
137220
// AddPath 为 node 的 path 路径处的对象添加一个子节点
138221
// path 路径表示的是子节点加入后的路径, 以 "/" 开头
139222
func AddPath(node *JsonNode, path string, value *JsonNode) error {
@@ -196,7 +279,7 @@ func (jn *JsonNode) Equal(patch *JsonNode) bool {
196279
func (jn *JsonNode) find(paths []string) (*JsonNode, bool) {
197280
root := jn
198281
for _, key := range paths {
199-
key = keyRestore(key)
282+
key = KeyRestore(key)
200283
switch root.Type {
201284
case JsonNodeTypeObject:
202285
r, ok := root.ChildrenMap[key]
@@ -400,42 +483,42 @@ func CopyPath(node *JsonNode, from, path string) error {
400483
}
401484

402485
func ATestPath(srcNode *JsonNode, path string, value *JsonNode) error {
403-
f, ok := srcNode.Find(path)
404-
if !ok {
405-
return GetJsonNodeError("test", fmt.Sprintf("%s not find", path))
406-
}
407-
if f.Type != value.Type {
408-
return GetJsonNodeError("test",
409-
fmt.Sprintf("types are not equal, one is %s, another is %s",
410-
f.Type.String(), value.Type.String()))
411-
}
412-
switch value.Type {
413-
case JsonNodeTypeValue:
414-
// [{"op": "test", "path": "a/b/c", "value":"123"}]
415-
if f.Value != value.Value {
416-
return GetJsonNodeError("test", valueAreNotEqual(f.Value, value.Value))
417-
}
418-
case JsonNodeTypeSlice:
419-
// [{"op": "test", "path": "a/b/c", "value":[123, 456]}]
420-
if len(f.Children) != len(value.Children) {
421-
return GetJsonNodeError("test", valueAreNotEqual(f.Children, value.Children))
422-
}
423-
for i, v := range value.Children {
424-
if !v.Equal(f.Children[i]) {
425-
return GetJsonNodeError("test", valueAreNotEqual(v, f.Children[i]))
426-
}
427-
}
428-
case JsonNodeTypeObject:
429-
if len(f.ChildrenMap) != len(value.ChildrenMap) {
430-
return GetJsonNodeError("test", valueAreNotEqual(f.ChildrenMap, value.ChildrenMap))
431-
}
432-
for k, v := range value.ChildrenMap {
433-
if !v.Equal(f.ChildrenMap[k]) {
434-
return GetJsonNodeError("test", valueAreNotEqual(v, f.ChildrenMap[k]))
435-
}
436-
}
437-
}
438-
return nil
486+
f, ok := srcNode.Find(path)
487+
if !ok {
488+
return GetJsonNodeError("test", fmt.Sprintf("%s not find", path))
489+
}
490+
if f.Type != value.Type {
491+
return GetJsonNodeError("test",
492+
fmt.Sprintf("types are not equal, one is %s, another is %s",
493+
f.Type.String(), value.Type.String()))
494+
}
495+
switch value.Type {
496+
case JsonNodeTypeValue:
497+
// [{"op": "test", "path": "a/b/c", "value":"123"}]
498+
if f.Value != value.Value {
499+
return GetJsonNodeError("test", valueAreNotEqual(f.Value, value.Value))
500+
}
501+
case JsonNodeTypeSlice:
502+
// [{"op": "test", "path": "a/b/c", "value":[123, 456]}]
503+
if len(f.Children) != len(value.Children) {
504+
return GetJsonNodeError("test", valueAreNotEqual(f.Children, value.Children))
505+
}
506+
for i, v := range value.Children {
507+
if !v.Equal(f.Children[i]) {
508+
return GetJsonNodeError("test", valueAreNotEqual(v, f.Children[i]))
509+
}
510+
}
511+
case JsonNodeTypeObject:
512+
if len(f.ChildrenMap) != len(value.ChildrenMap) {
513+
return GetJsonNodeError("test", valueAreNotEqual(f.ChildrenMap, value.ChildrenMap))
514+
}
515+
for k, v := range value.ChildrenMap {
516+
if !v.Equal(f.ChildrenMap[k]) {
517+
return GetJsonNodeError("test", valueAreNotEqual(v, f.ChildrenMap[k]))
518+
}
519+
}
520+
}
521+
return nil
439522
}
440523

441524
func splitKey(node *JsonNode, path string) (string, *JsonNode, error) {
@@ -459,5 +542,5 @@ func keyMustCanBeConvertibleToInt(got interface{}) string {
459542
}
460543

461544
func valueAreNotEqual(one, another interface{}) string {
462-
return fmt.Sprintf("value are not equal, one is %v, another is %v", one, another)
545+
return fmt.Sprintf("value are not equal, one is %v, another is %v", one, another)
463546
}

‎deepcopy.go

+19-18
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
package json_diff
22

33
import (
4+
"github.com/520MianXiangDuiXiang520/json-diff/decode"
45
"github.com/pkg/errors"
56
)
67

7-
func copySlice(src *JsonNode) (*JsonNode, error) {
8+
func copySlice(src *decode.JsonNode) (*decode.JsonNode, error) {
89
size := len(src.Children)
9-
res := NewSliceNode(make([]*JsonNode, size), int(src.Level))
10+
res := decode.NewSliceNode(make([]*decode.JsonNode, size), int(src.Level))
1011
for i, child := range src.Children {
11-
var newNode *JsonNode
12+
var newNode *decode.JsonNode
1213
var err error
1314
switch child.Type {
14-
case JsonNodeTypeSlice:
15+
case decode.JsonNodeTypeSlice:
1516
newNode, err = copySlice(child)
1617
if err != nil {
1718
return nil, errors.Wrapf(err, "fail to copy %dst of Slice type", i)
1819
}
19-
case JsonNodeTypeObject:
20+
case decode.JsonNodeTypeObject:
2021
newNode, err = copyObject(child)
2122
if err != nil {
2223
return nil, errors.Wrapf(err, "fail to copy %dst of Object type", i)
2324
}
24-
case JsonNodeTypeValue:
25+
case decode.JsonNodeTypeValue:
2526
newNode, err = copyValue(child)
2627
if err != nil {
2728
return nil, errors.Wrapf(err, "fail to copy %dst of Value type", i)
@@ -32,27 +33,27 @@ func copySlice(src *JsonNode) (*JsonNode, error) {
3233
return res, nil
3334
}
3435

35-
func copyValue(src *JsonNode) (*JsonNode, error) {
36-
return NewValueNode(src.Value, int(src.Level)), nil
36+
func copyValue(src *decode.JsonNode) (*decode.JsonNode, error) {
37+
return decode.NewValueNode(src.Value, int(src.Level)), nil
3738
}
3839

39-
func copyObject(src *JsonNode) (*JsonNode, error) {
40-
res := NewObjectNode("", map[string]*JsonNode{}, int(src.Level))
40+
func copyObject(src *decode.JsonNode) (*decode.JsonNode, error) {
41+
res := decode.NewObjectNode("", map[string]*decode.JsonNode{}, int(src.Level))
4142
for k, v := range src.ChildrenMap {
42-
var newNode *JsonNode
43+
var newNode *decode.JsonNode
4344
var err error
4445
switch v.Type {
45-
case JsonNodeTypeObject:
46+
case decode.JsonNodeTypeObject:
4647
newNode, err = copyObject(v)
4748
if err != nil {
4849
return nil, errors.Wrapf(err, "failed to copy %s of Object type", k)
4950
}
50-
case JsonNodeTypeSlice:
51+
case decode.JsonNodeTypeSlice:
5152
newNode, err = copySlice(v)
5253
if err != nil {
5354
return nil, errors.Wrapf(err, "failed to copy %s of Slice type", k)
5455
}
55-
case JsonNodeTypeValue:
56+
case decode.JsonNodeTypeValue:
5657
newNode, err = copyValue(v)
5758
if err != nil {
5859
return nil, errors.Wrapf(err, "failed to copy %s of Value type", k)
@@ -63,13 +64,13 @@ func copyObject(src *JsonNode) (*JsonNode, error) {
6364
return res, nil
6465
}
6566

66-
func DeepCopy(src *JsonNode) (*JsonNode, error) {
67+
func DeepCopy(src *decode.JsonNode) (*decode.JsonNode, error) {
6768
switch src.Type {
68-
case JsonNodeTypeObject:
69+
case decode.JsonNodeTypeObject:
6970
return copyObject(src)
70-
case JsonNodeTypeSlice:
71+
case decode.JsonNodeTypeSlice:
7172
return copySlice(src)
72-
case JsonNodeTypeValue:
73+
case decode.JsonNodeTypeValue:
7374
return copyValue(src)
7475
}
7576
return nil, errors.New("src has an unknown type")

0 commit comments

Comments
 (0)