mirror of
https://gitee.com/johng/gf.git
synced 2024-11-30 03:07:45 +08:00
improve function Set for package gjson
This commit is contained in:
parent
14d5fd3e11
commit
4d501fd2f4
@ -86,6 +86,7 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
|
||||
}
|
||||
|
||||
case []interface{}:
|
||||
// A string key.
|
||||
if !gstr.IsNumeric(array[i]) {
|
||||
if i == length-1 {
|
||||
*pointer = map[string]interface{}{array[i]: value}
|
||||
@ -97,23 +98,24 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
valn, err := strconv.Atoi(array[i])
|
||||
// Numeric index.
|
||||
valueNum, err := strconv.Atoi(array[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Leaf node.
|
||||
|
||||
if i == length-1 {
|
||||
if len((*pointer).([]interface{})) > valn {
|
||||
// Leaf node.
|
||||
if len((*pointer).([]interface{})) > valueNum {
|
||||
if removed && value == nil {
|
||||
// Deleting element.
|
||||
if pparent == nil {
|
||||
*pointer = append((*pointer).([]interface{})[:valn], (*pointer).([]interface{})[valn+1:]...)
|
||||
*pointer = append((*pointer).([]interface{})[:valueNum], (*pointer).([]interface{})[valueNum+1:]...)
|
||||
} else {
|
||||
j.setPointerWithValue(pparent, array[i-1], append((*pointer).([]interface{})[:valn], (*pointer).([]interface{})[valn+1:]...))
|
||||
j.setPointerWithValue(pparent, array[i-1], append((*pointer).([]interface{})[:valueNum], (*pointer).([]interface{})[valueNum+1:]...))
|
||||
}
|
||||
} else {
|
||||
(*pointer).([]interface{})[valn] = value
|
||||
(*pointer).([]interface{})[valueNum] = value
|
||||
}
|
||||
} else {
|
||||
if removed && value == nil {
|
||||
@ -124,19 +126,33 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
|
||||
j.setPointerWithValue(pointer, array[i], value)
|
||||
} else {
|
||||
// It is not the root node.
|
||||
s := make([]interface{}, valn+1)
|
||||
s := make([]interface{}, valueNum+1)
|
||||
copy(s, (*pointer).([]interface{}))
|
||||
s[valn] = value
|
||||
s[valueNum] = value
|
||||
j.setPointerWithValue(pparent, array[i-1], s)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Branch node.
|
||||
if gstr.IsNumeric(array[i+1]) {
|
||||
n, _ := strconv.Atoi(array[i+1])
|
||||
if len((*pointer).([]interface{})) > valn {
|
||||
(*pointer).([]interface{})[valn] = make([]interface{}, n+1)
|
||||
pparent = pointer
|
||||
pointer = &(*pointer).([]interface{})[valn]
|
||||
pSlice := (*pointer).([]interface{})
|
||||
if len(pSlice) > valueNum {
|
||||
item := pSlice[valueNum]
|
||||
if s, ok := item.([]interface{}); ok {
|
||||
for i := 0; i < n-len(s); i++ {
|
||||
s = append(s, nil)
|
||||
}
|
||||
pparent = pointer
|
||||
pointer = &pSlice[valueNum]
|
||||
} else {
|
||||
if removed && value == nil {
|
||||
goto done
|
||||
}
|
||||
var v interface{} = make([]interface{}, n+1)
|
||||
pparent = j.setPointerWithValue(pointer, array[i], v)
|
||||
pointer = &v
|
||||
}
|
||||
} else {
|
||||
if removed && value == nil {
|
||||
goto done
|
||||
@ -146,14 +162,26 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
|
||||
pointer = &v
|
||||
}
|
||||
} else {
|
||||
v := (*pointer).([]interface{})
|
||||
if len(v) > valn {
|
||||
pSlice := (*pointer).([]interface{})
|
||||
if len(pSlice) > valueNum {
|
||||
pparent = pointer
|
||||
pointer = &(*pointer).([]interface{})[valn]
|
||||
pointer = &(*pointer).([]interface{})[valueNum]
|
||||
} else {
|
||||
var v interface{} = make(map[string]interface{})
|
||||
pparent = j.setPointerWithValue(pointer, array[i], v)
|
||||
pointer = &v
|
||||
s := make([]interface{}, valueNum+1)
|
||||
copy(s, pSlice)
|
||||
s[valueNum] = make(map[string]interface{})
|
||||
if pparent != nil {
|
||||
// i > 0
|
||||
j.setPointerWithValue(pparent, array[i-1], s)
|
||||
pparent = pointer
|
||||
pointer = &s[valueNum]
|
||||
} else {
|
||||
// i = 0
|
||||
var v interface{} = s
|
||||
*pointer = v
|
||||
pparent = pointer
|
||||
pointer = &s[valueNum]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -177,19 +205,24 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
|
||||
pparent = pointer
|
||||
}
|
||||
} else {
|
||||
var v interface{} = make(map[string]interface{})
|
||||
var v1, v2 interface{}
|
||||
if i == length-1 {
|
||||
v = map[string]interface{}{
|
||||
v1 = map[string]interface{}{
|
||||
array[i]: value,
|
||||
}
|
||||
} else {
|
||||
v1 = map[string]interface{}{
|
||||
array[i]: nil,
|
||||
}
|
||||
}
|
||||
if pparent != nil {
|
||||
pparent = j.setPointerWithValue(pparent, array[i-1], v)
|
||||
pparent = j.setPointerWithValue(pparent, array[i-1], v1)
|
||||
} else {
|
||||
*pointer = v
|
||||
*pointer = v1
|
||||
pparent = pointer
|
||||
}
|
||||
pointer = &v
|
||||
v2 = v1.(map[string]interface{})[array[i]]
|
||||
pointer = &v2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ func Test_Basic(t *testing.T) {
|
||||
j = gjson.New(`[1,2,3]`)
|
||||
err = j.Remove("0.3")
|
||||
t.Assert(err, nil)
|
||||
t.Assert(len(j.Get("0").([]interface{})), 3)
|
||||
t.Assert(j.Get("0"), 1)
|
||||
|
||||
j = gjson.New(`[1,2,3]`)
|
||||
err = j.Remove("0.a")
|
||||
|
17
encoding/gjson/gjson_z_unit_internal_test.go
Normal file
17
encoding/gjson/gjson_z_unit_internal_test.go
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gjson
|
||||
|
||||
//func Test_Load_YAML3(t *testing.T) {
|
||||
// data := []byte(`
|
||||
//bb = """
|
||||
// dig := dig; END;"""
|
||||
//`)
|
||||
// gtest.C(t, func(t *gtest.T) {
|
||||
// t.Assert(checkDataType(data), "toml")
|
||||
// })
|
||||
//}
|
@ -8,6 +8,9 @@ package gjson_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/test/gtest"
|
||||
"github.com/gogf/gf/text/gstr"
|
||||
"testing"
|
||||
|
||||
"github.com/gogf/gf/encoding/gjson"
|
||||
@ -31,17 +34,13 @@ func Test_Set1(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_Set2(t *testing.T) {
|
||||
e := []byte(`[[null,1]]`)
|
||||
p := gjson.New([]string{"a"})
|
||||
p.Set("0.1", 1)
|
||||
if c, err := p.ToJson(); err == nil {
|
||||
|
||||
if bytes.Compare(c, e) != 0 {
|
||||
t.Error("expect:", string(e))
|
||||
}
|
||||
} else {
|
||||
t.Error(err)
|
||||
}
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
e := `[[null,1]]`
|
||||
p := gjson.New([]string{"a"})
|
||||
p.Set("0.1", 1)
|
||||
s := p.MustToJsonString()
|
||||
t.Assert(s, e)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Set3(t *testing.T) {
|
||||
@ -51,7 +50,6 @@ func Test_Set3(t *testing.T) {
|
||||
"k1": "v1",
|
||||
})
|
||||
if c, err := p.ToJson(); err == nil {
|
||||
|
||||
if bytes.Compare(c, e) != 0 {
|
||||
t.Error("expect:", string(e))
|
||||
}
|
||||
@ -227,3 +225,107 @@ func Test_Set14(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Set15(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
j := gjson.New(nil)
|
||||
|
||||
t.Assert(j.Set("root.0.k1", "v1"), nil)
|
||||
t.Assert(j.Set("root.1.k2", "v2"), nil)
|
||||
t.Assert(j.Set("k", "v"), nil)
|
||||
|
||||
s, err := j.ToJsonString()
|
||||
t.Assert(err, nil)
|
||||
t.Assert(
|
||||
gstr.Contains(s, `"root":[{"k1":"v1"},{"k2":"v2"}`) ||
|
||||
gstr.Contains(s, `"root":[{"k2":"v2"},{"k1":"v1"}`),
|
||||
true,
|
||||
)
|
||||
t.Assert(
|
||||
gstr.Contains(s, `{"k":"v"`) ||
|
||||
gstr.Contains(s, `"k":"v"}`),
|
||||
true,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Set16(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
j := gjson.New(nil)
|
||||
|
||||
t.Assert(j.Set("processors.0.set.0value", "1"), nil)
|
||||
t.Assert(j.Set("processors.0.set.0field", "2"), nil)
|
||||
t.Assert(j.Set("description", "3"), nil)
|
||||
|
||||
s, err := j.ToJsonString()
|
||||
t.Assert(err, nil)
|
||||
t.Assert(
|
||||
gstr.Contains(s, `"processors":[{"set":{"0field":"2","0value":"1"}}]`) ||
|
||||
gstr.Contains(s, `"processors":[{"set":{"0value":"1","0field":"2"}}]`),
|
||||
true,
|
||||
)
|
||||
t.Assert(
|
||||
gstr.Contains(s, `{"description":"3"`) || gstr.Contains(s, `"description":"3"}`),
|
||||
true,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Set17(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
j := gjson.New(nil)
|
||||
|
||||
t.Assert(j.Set("0.k1", "v1"), nil)
|
||||
t.Assert(j.Set("1.k2", "v2"), nil)
|
||||
// overwrite the previous slice.
|
||||
t.Assert(j.Set("k", "v"), nil)
|
||||
|
||||
s, err := j.ToJsonString()
|
||||
t.Assert(err, nil)
|
||||
t.Assert(s, `{"k":"v"}`)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Set18(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
j := gjson.New(nil)
|
||||
|
||||
t.Assert(j.Set("0.1.k1", "v1"), nil)
|
||||
t.Assert(j.Set("0.2.k2", "v2"), nil)
|
||||
s, err := j.ToJsonString()
|
||||
t.Assert(err, nil)
|
||||
t.Assert(s, `[[null,{"k1":"v1"},{"k2":"v2"}]]`)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Set19(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
j := gjson.New(nil)
|
||||
|
||||
t.Assert(j.Set("0.1.1.k1", "v1"), nil)
|
||||
t.Assert(j.Set("0.2.1.k2", "v2"), nil)
|
||||
s, err := j.ToJsonString()
|
||||
t.Assert(err, nil)
|
||||
t.Assert(s, `[[null,[null,{"k1":"v1"}],[null,{"k2":"v2"}]]]`)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Set20(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
j := gjson.New(nil)
|
||||
|
||||
t.Assert(j.Set("k1", "v1"), nil)
|
||||
t.Assert(j.Set("k2", g.Slice{1, 2, 3}), nil)
|
||||
t.Assert(j.Set("k2.1", 20), nil)
|
||||
t.Assert(j.Set("k2.2", g.Map{"k3": "v3"}), nil)
|
||||
s, err := j.ToJsonString()
|
||||
t.Assert(err, nil)
|
||||
t.Assert(gstr.InArray(
|
||||
g.SliceStr{
|
||||
`{"k1":"v1","k2":[1,20,{"k3":"v3"}]}`,
|
||||
`{"k2":[1,20,{"k3":"v3"}],"k1":"v1"}`,
|
||||
},
|
||||
s,
|
||||
), true)
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user