mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
improve package gjson/gvar
This commit is contained in:
@ -106,11 +106,6 @@ func (v *Var) Int() int {
|
||||
return gconv.Int(v.Val())
|
||||
}
|
||||
|
||||
// Ints converts and returns <v> as []int.
|
||||
func (v *Var) Ints() []int {
|
||||
return gconv.Ints(v.Val())
|
||||
}
|
||||
|
||||
// Int8 converts and returns <v> as int8.
|
||||
func (v *Var) Int8() int8 {
|
||||
return gconv.Int8(v.Val())
|
||||
@ -136,11 +131,6 @@ func (v *Var) Uint() uint {
|
||||
return gconv.Uint(v.Val())
|
||||
}
|
||||
|
||||
// Uints converts and returns <v> as []uint.
|
||||
func (v *Var) Uints() []uint {
|
||||
return gconv.Uints(v.Val())
|
||||
}
|
||||
|
||||
// Uint8 converts and returns <v> as uint8.
|
||||
func (v *Var) Uint8() uint8 {
|
||||
return gconv.Uint8(v.Val())
|
||||
@ -171,44 +161,6 @@ func (v *Var) Float64() float64 {
|
||||
return gconv.Float64(v.Val())
|
||||
}
|
||||
|
||||
// Floats converts and returns <v> as []float64.
|
||||
func (v *Var) Floats() []float64 {
|
||||
return gconv.Floats(v.Val())
|
||||
}
|
||||
|
||||
// Strings converts and returns <v> as []string.
|
||||
func (v *Var) Strings() []string {
|
||||
return gconv.Strings(v.Val())
|
||||
}
|
||||
|
||||
// Interfaces converts and returns <v> as []interfaces{}.
|
||||
func (v *Var) Interfaces() []interface{} {
|
||||
return gconv.Interfaces(v.Val())
|
||||
}
|
||||
|
||||
// Slice is alias of Interfaces.
|
||||
func (v *Var) Slice() []interface{} {
|
||||
return v.Interfaces()
|
||||
}
|
||||
|
||||
// Array is alias of Interfaces.
|
||||
func (v *Var) Array() []interface{} {
|
||||
return v.Interfaces()
|
||||
}
|
||||
|
||||
// Vars converts and returns <v> as []Var.
|
||||
func (v *Var) Vars() []*Var {
|
||||
array := gconv.Interfaces(v.Val())
|
||||
if len(array) == 0 {
|
||||
return nil
|
||||
}
|
||||
vars := make([]*Var, len(array))
|
||||
for k, v := range array {
|
||||
vars[k] = New(v)
|
||||
}
|
||||
return vars
|
||||
}
|
||||
|
||||
// Time converts and returns <v> as time.Time.
|
||||
// The parameter <format> specifies the format of the time string using gtime,
|
||||
// eg: Y-m-d H:i:s.
|
||||
|
||||
77
container/gvar/gvar_slice.go
Normal file
77
container/gvar/gvar_slice.go
Normal file
@ -0,0 +1,77 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). 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 gvar
|
||||
|
||||
import "github.com/gogf/gf/util/gconv"
|
||||
|
||||
// Ints converts and returns <v> as []int.
|
||||
func (v *Var) Ints() []int {
|
||||
return gconv.Ints(v.Val())
|
||||
}
|
||||
|
||||
// Int64s converts and returns <v> as []int64.
|
||||
func (v *Var) Int64s() []int64 {
|
||||
return gconv.Int64s(v.Val())
|
||||
}
|
||||
|
||||
// Uints converts and returns <v> as []uint.
|
||||
func (v *Var) Uints() []uint {
|
||||
return gconv.Uints(v.Val())
|
||||
}
|
||||
|
||||
// Uint64s converts and returns <v> as []uint64.
|
||||
func (v *Var) Uint64s() []uint64 {
|
||||
return gconv.Uint64s(v.Val())
|
||||
}
|
||||
|
||||
// Floats is alias of Float64s.
|
||||
func (v *Var) Floats() []float64 {
|
||||
return gconv.Floats(v.Val())
|
||||
}
|
||||
|
||||
// Float32s converts and returns <v> as []float32.
|
||||
func (v *Var) Float32s() []float32 {
|
||||
return gconv.Float32s(v.Val())
|
||||
}
|
||||
|
||||
// Float64s converts and returns <v> as []float64.
|
||||
func (v *Var) Float64s() []float64 {
|
||||
return gconv.Float64s(v.Val())
|
||||
}
|
||||
|
||||
// Strings converts and returns <v> as []string.
|
||||
func (v *Var) Strings() []string {
|
||||
return gconv.Strings(v.Val())
|
||||
}
|
||||
|
||||
// Interfaces converts and returns <v> as []interfaces{}.
|
||||
func (v *Var) Interfaces() []interface{} {
|
||||
return gconv.Interfaces(v.Val())
|
||||
}
|
||||
|
||||
// Slice is alias of Interfaces.
|
||||
func (v *Var) Slice() []interface{} {
|
||||
return v.Interfaces()
|
||||
}
|
||||
|
||||
// Array is alias of Interfaces.
|
||||
func (v *Var) Array() []interface{} {
|
||||
return v.Interfaces()
|
||||
}
|
||||
|
||||
// Vars converts and returns <v> as []Var.
|
||||
func (v *Var) Vars() []*Var {
|
||||
array := gconv.Interfaces(v.Val())
|
||||
if len(array) == 0 {
|
||||
return nil
|
||||
}
|
||||
vars := make([]*Var, len(array))
|
||||
for k, v := range array {
|
||||
vars[k] = New(v)
|
||||
}
|
||||
return vars
|
||||
}
|
||||
@ -221,62 +221,6 @@ func Test_Float64(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Ints(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []int{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.Assert(objOne.Ints()[0], arr[0])
|
||||
})
|
||||
}
|
||||
func Test_Floats(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []float64{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.Assert(objOne.Floats()[0], arr[0])
|
||||
})
|
||||
}
|
||||
func Test_Strings(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []string{"hello", "world"}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.Assert(objOne.Strings()[0], arr[0])
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Interfaces(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []int{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.Assert(objOne.Interfaces(), arr)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Slice(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []int{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.Assert(objOne.Slice(), arr)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Array(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []int{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, false)
|
||||
t.Assert(objOne.Array(), arr)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Vars(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []int{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, false)
|
||||
t.Assert(len(objOne.Vars()), 5)
|
||||
t.Assert(objOne.Vars()[0].Int(), 1)
|
||||
t.Assert(objOne.Vars()[4].Int(), 5)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Time(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var timeUnix int64 = 1556242660
|
||||
|
||||
@ -14,7 +14,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_Json(t *testing.T) {
|
||||
func TestVar_Json(t *testing.T) {
|
||||
// Marshal
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
s := "i love gf"
|
||||
|
||||
@ -13,7 +13,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_ListItemValues_Map(t *testing.T) {
|
||||
func TestVar_ListItemValues_Map(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
listMap := g.List{
|
||||
g.Map{"id": 1, "score": 100},
|
||||
@ -34,7 +34,7 @@ func Test_ListItemValues_Map(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_ListItemValues_Struct(t *testing.T) {
|
||||
func TestVar_ListItemValues_Struct(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type T struct {
|
||||
Id int
|
||||
@ -78,7 +78,7 @@ func Test_ListItemValues_Struct(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_ListItemValuesUnique(t *testing.T) {
|
||||
func TestVar_ListItemValuesUnique(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
listMap := g.List{
|
||||
g.Map{"id": 1, "score": 100},
|
||||
|
||||
@ -13,7 +13,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_Map(t *testing.T) {
|
||||
func TestVar_Map(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
m := g.Map{
|
||||
"k1": "v1",
|
||||
@ -24,3 +24,58 @@ func Test_Map(t *testing.T) {
|
||||
t.Assert(objOne.Map()["k2"], m["k2"])
|
||||
})
|
||||
}
|
||||
|
||||
func TestVar_MapToMap(t *testing.T) {
|
||||
// map[int]int -> map[string]string
|
||||
// empty original map.
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
m1 := g.MapIntInt{}
|
||||
m2 := g.MapStrStr{}
|
||||
t.Assert(gvar.New(m1).MapToMap(&m2), nil)
|
||||
t.Assert(len(m1), len(m2))
|
||||
})
|
||||
// map[int]int -> map[string]string
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
m1 := g.MapIntInt{
|
||||
1: 100,
|
||||
2: 200,
|
||||
}
|
||||
m2 := g.MapStrStr{}
|
||||
t.Assert(gvar.New(m1).MapToMap(&m2), nil)
|
||||
t.Assert(m2["1"], m1[1])
|
||||
t.Assert(m2["2"], m1[2])
|
||||
})
|
||||
// map[string]interface{} -> map[string]string
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
m1 := g.Map{
|
||||
"k1": "v1",
|
||||
"k2": "v2",
|
||||
}
|
||||
m2 := g.MapStrStr{}
|
||||
t.Assert(gvar.New(m1).MapToMap(&m2), nil)
|
||||
t.Assert(m2["k1"], m1["k1"])
|
||||
t.Assert(m2["k2"], m1["k2"])
|
||||
})
|
||||
// map[string]string -> map[string]interface{}
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
m1 := g.MapStrStr{
|
||||
"k1": "v1",
|
||||
"k2": "v2",
|
||||
}
|
||||
m2 := g.Map{}
|
||||
t.Assert(gvar.New(m1).MapToMap(&m2), nil)
|
||||
t.Assert(m2["k1"], m1["k1"])
|
||||
t.Assert(m2["k2"], m1["k2"])
|
||||
})
|
||||
// map[string]interface{} -> map[interface{}]interface{}
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
m1 := g.MapStrStr{
|
||||
"k1": "v1",
|
||||
"k2": "v2",
|
||||
}
|
||||
m2 := g.MapAnyAny{}
|
||||
t.Assert(gvar.New(m1).MapToMap(&m2), nil)
|
||||
t.Assert(m2["k1"], m1["k1"])
|
||||
t.Assert(m2["k2"], m1["k2"])
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,69 +0,0 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). 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 gvar_test
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/container/gvar"
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/test/gtest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_MapToMap(t *testing.T) {
|
||||
// map[int]int -> map[string]string
|
||||
// empty original map.
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
m1 := g.MapIntInt{}
|
||||
m2 := g.MapStrStr{}
|
||||
t.Assert(gvar.New(m1).MapToMap(&m2), nil)
|
||||
t.Assert(len(m1), len(m2))
|
||||
})
|
||||
// map[int]int -> map[string]string
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
m1 := g.MapIntInt{
|
||||
1: 100,
|
||||
2: 200,
|
||||
}
|
||||
m2 := g.MapStrStr{}
|
||||
t.Assert(gvar.New(m1).MapToMap(&m2), nil)
|
||||
t.Assert(m2["1"], m1[1])
|
||||
t.Assert(m2["2"], m1[2])
|
||||
})
|
||||
// map[string]interface{} -> map[string]string
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
m1 := g.Map{
|
||||
"k1": "v1",
|
||||
"k2": "v2",
|
||||
}
|
||||
m2 := g.MapStrStr{}
|
||||
t.Assert(gvar.New(m1).MapToMap(&m2), nil)
|
||||
t.Assert(m2["k1"], m1["k1"])
|
||||
t.Assert(m2["k2"], m1["k2"])
|
||||
})
|
||||
// map[string]string -> map[string]interface{}
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
m1 := g.MapStrStr{
|
||||
"k1": "v1",
|
||||
"k2": "v2",
|
||||
}
|
||||
m2 := g.Map{}
|
||||
t.Assert(gvar.New(m1).MapToMap(&m2), nil)
|
||||
t.Assert(m2["k1"], m1["k1"])
|
||||
t.Assert(m2["k2"], m1["k2"])
|
||||
})
|
||||
// map[string]interface{} -> map[interface{}]interface{}
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
m1 := g.MapStrStr{
|
||||
"k1": "v1",
|
||||
"k2": "v2",
|
||||
}
|
||||
m2 := g.MapAnyAny{}
|
||||
t.Assert(gvar.New(m1).MapToMap(&m2), nil)
|
||||
t.Assert(m2["k1"], m1["k1"])
|
||||
t.Assert(m2["k2"], m1["k2"])
|
||||
})
|
||||
}
|
||||
111
container/gvar/gvar_z_unit_slice_test.go
Normal file
111
container/gvar/gvar_z_unit_slice_test.go
Normal file
@ -0,0 +1,111 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). 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 gvar_test
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/container/gvar"
|
||||
"github.com/gogf/gf/test/gtest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVar_Ints(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []int{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.Assert(objOne.Ints()[0], arr[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestVar_Uints(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []int{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.Assert(objOne.Uints()[0], arr[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestVar_Int64s(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []int{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.Assert(objOne.Int64s()[0], arr[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestVar_Uint64s(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []int{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.Assert(objOne.Uint64s()[0], arr[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestVar_Floats(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []float64{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.Assert(objOne.Floats()[0], arr[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestVar_Float32s(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []float32{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.AssertEQ(objOne.Float32s(), arr)
|
||||
})
|
||||
}
|
||||
|
||||
func TestVar_Float64s(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []float64{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.AssertEQ(objOne.Float64s(), arr)
|
||||
})
|
||||
}
|
||||
|
||||
func TestVar_Strings(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []string{"hello", "world"}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.Assert(objOne.Strings()[0], arr[0])
|
||||
})
|
||||
}
|
||||
|
||||
func TestVar_Interfaces(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []int{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.Assert(objOne.Interfaces(), arr)
|
||||
})
|
||||
}
|
||||
|
||||
func TestVar_Slice(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []int{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, true)
|
||||
t.Assert(objOne.Slice(), arr)
|
||||
})
|
||||
}
|
||||
|
||||
func TestVar_Array(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []int{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, false)
|
||||
t.Assert(objOne.Array(), arr)
|
||||
})
|
||||
}
|
||||
|
||||
func TestVar_Vars(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var arr = []int{1, 2, 3, 4, 5}
|
||||
objOne := gvar.New(arr, false)
|
||||
t.Assert(len(objOne.Vars()), 5)
|
||||
t.Assert(objOne.Vars()[0].Int(), 1)
|
||||
t.Assert(objOne.Vars()[4].Int(), 5)
|
||||
})
|
||||
}
|
||||
@ -14,7 +14,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_Struct(t *testing.T) {
|
||||
func TestVar_Struct(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type StTest struct {
|
||||
Test int
|
||||
@ -42,7 +42,7 @@ func Test_Struct(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Var_Attribute_Struct(t *testing.T) {
|
||||
func TestVar_Var_Attribute_Struct(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type User struct {
|
||||
Uid int
|
||||
|
||||
@ -19,7 +19,7 @@ import (
|
||||
|
||||
const (
|
||||
// Separator char for hierarchical data access.
|
||||
gDEFAULT_SPLIT_CHAR = '.'
|
||||
defaultSplitChar = '.'
|
||||
)
|
||||
|
||||
// The customized JSON struct.
|
||||
@ -30,6 +30,13 @@ type Json struct {
|
||||
vc bool // Violence Check(false in default), which is used to access data when the hierarchical data key contains separator char.
|
||||
}
|
||||
|
||||
// Option for Json object creating.
|
||||
type Option struct {
|
||||
Safe bool // Mark this object is for in concurrent-safe usage.
|
||||
Tags string // Custom priority tags for decoding.
|
||||
StrNumber bool // StrNumber causes the Decoder to unmarshal a number into an interface{} as a string instead of as a float64.
|
||||
}
|
||||
|
||||
// setValue sets <value> to <j> by <pattern>.
|
||||
// Note:
|
||||
// 1. If value is nil and removed is true, means deleting this value;
|
||||
|
||||
@ -24,6 +24,11 @@ func (j *Json) Value() interface{} {
|
||||
return *(j.p)
|
||||
}
|
||||
|
||||
// Var returns the json value as *gvar.Var.
|
||||
func (j *Json) Var() *gvar.Var {
|
||||
return gvar.New(j.Value())
|
||||
}
|
||||
|
||||
// IsNil checks whether the value pointed by <j> is nil.
|
||||
func (j *Json) IsNil() bool {
|
||||
j.mu.RLock()
|
||||
|
||||
@ -42,15 +42,27 @@ func New(data interface{}, safe ...bool) *Json {
|
||||
// The parameter <safe> specifies whether using this Json object in concurrent-safe context, which
|
||||
// is false in default.
|
||||
func NewWithTag(data interface{}, tags string, safe ...bool) *Json {
|
||||
j := (*Json)(nil)
|
||||
option := Option{
|
||||
Tags: tags,
|
||||
}
|
||||
if len(safe) > 0 && safe[0] {
|
||||
option.Safe = true
|
||||
}
|
||||
return NewWithOption(data, option)
|
||||
}
|
||||
|
||||
// NewWithOption creates a Json object with any variable type of <data>, but <data> should be a map
|
||||
// or slice for data access reason, or it will make no sense.
|
||||
func NewWithOption(data interface{}, option Option) *Json {
|
||||
var j *Json
|
||||
switch data.(type) {
|
||||
case string, []byte:
|
||||
if r, err := LoadContent(gconv.Bytes(data)); err == nil {
|
||||
if r, err := loadContentWithOption(data, option); err == nil {
|
||||
j = r
|
||||
} else {
|
||||
j = &Json{
|
||||
p: &data,
|
||||
c: byte(gDEFAULT_SPLIT_CHAR),
|
||||
c: byte(defaultSplitChar),
|
||||
vc: false,
|
||||
}
|
||||
}
|
||||
@ -69,26 +81,26 @@ func NewWithTag(data interface{}, tags string, safe ...bool) *Json {
|
||||
i = gconv.Interfaces(data)
|
||||
j = &Json{
|
||||
p: &i,
|
||||
c: byte(gDEFAULT_SPLIT_CHAR),
|
||||
c: byte(defaultSplitChar),
|
||||
vc: false,
|
||||
}
|
||||
case reflect.Map, reflect.Struct:
|
||||
i := interface{}(nil)
|
||||
i = gconv.MapDeep(data, tags)
|
||||
i = gconv.MapDeep(data, option.Tags)
|
||||
j = &Json{
|
||||
p: &i,
|
||||
c: byte(gDEFAULT_SPLIT_CHAR),
|
||||
c: byte(defaultSplitChar),
|
||||
vc: false,
|
||||
}
|
||||
default:
|
||||
j = &Json{
|
||||
p: &data,
|
||||
c: byte(gDEFAULT_SPLIT_CHAR),
|
||||
c: byte(defaultSplitChar),
|
||||
vc: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
j.mu = rwmutex.New(safe...)
|
||||
j.mu = rwmutex.New(option.Safe)
|
||||
return j
|
||||
}
|
||||
|
||||
@ -99,42 +111,133 @@ func Load(path string, safe ...bool) (*Json, error) {
|
||||
} else {
|
||||
path = p
|
||||
}
|
||||
return doLoadContent(gfile.Ext(path), gfile.GetBytesWithCache(path), safe...)
|
||||
option := Option{}
|
||||
if len(safe) > 0 && safe[0] {
|
||||
option.Safe = true
|
||||
}
|
||||
return doLoadContentWithOption(gfile.Ext(path), gfile.GetBytesWithCache(path), option)
|
||||
}
|
||||
|
||||
// LoadJson creates a Json object from given JSON format content.
|
||||
func LoadJson(data interface{}, safe ...bool) (*Json, error) {
|
||||
return doLoadContent("json", gconv.Bytes(data), safe...)
|
||||
option := Option{}
|
||||
if len(safe) > 0 && safe[0] {
|
||||
option.Safe = true
|
||||
}
|
||||
return doLoadContentWithOption("json", gconv.Bytes(data), option)
|
||||
}
|
||||
|
||||
// LoadXml creates a Json object from given XML format content.
|
||||
func LoadXml(data interface{}, safe ...bool) (*Json, error) {
|
||||
return doLoadContent("xml", gconv.Bytes(data), safe...)
|
||||
option := Option{}
|
||||
if len(safe) > 0 && safe[0] {
|
||||
option.Safe = true
|
||||
}
|
||||
return doLoadContentWithOption("xml", gconv.Bytes(data), option)
|
||||
}
|
||||
|
||||
// LoadIni creates a Json object from given INI format content.
|
||||
func LoadIni(data interface{}, safe ...bool) (*Json, error) {
|
||||
return doLoadContent("ini", gconv.Bytes(data), safe...)
|
||||
option := Option{}
|
||||
if len(safe) > 0 && safe[0] {
|
||||
option.Safe = true
|
||||
}
|
||||
return doLoadContentWithOption("ini", gconv.Bytes(data), option)
|
||||
}
|
||||
|
||||
// LoadYaml creates a Json object from given YAML format content.
|
||||
func LoadYaml(data interface{}, safe ...bool) (*Json, error) {
|
||||
return doLoadContent("yaml", gconv.Bytes(data), safe...)
|
||||
option := Option{}
|
||||
if len(safe) > 0 && safe[0] {
|
||||
option.Safe = true
|
||||
}
|
||||
return doLoadContentWithOption("yaml", gconv.Bytes(data), option)
|
||||
}
|
||||
|
||||
// LoadToml creates a Json object from given TOML format content.
|
||||
func LoadToml(data interface{}, safe ...bool) (*Json, error) {
|
||||
return doLoadContent("toml", gconv.Bytes(data), safe...)
|
||||
option := Option{}
|
||||
if len(safe) > 0 && safe[0] {
|
||||
option.Safe = true
|
||||
}
|
||||
return doLoadContentWithOption("toml", gconv.Bytes(data), option)
|
||||
}
|
||||
|
||||
// LoadContent creates a Json object from given content, it checks the data type of <content>
|
||||
// automatically, supporting data content type as follows:
|
||||
// JSON, XML, INI, YAML and TOML.
|
||||
func LoadContent(data interface{}, safe ...bool) (*Json, error) {
|
||||
content := gconv.Bytes(data)
|
||||
if len(content) == 0 {
|
||||
return New(nil, safe...), nil
|
||||
}
|
||||
return LoadContentType(checkDataType(content), content, safe...)
|
||||
}
|
||||
|
||||
// LoadContentType creates a Json object from given type and content,
|
||||
// supporting data content type as follows:
|
||||
// JSON, XML, INI, YAML and TOML.
|
||||
func LoadContentType(dataType string, data interface{}, safe ...bool) (*Json, error) {
|
||||
content := gconv.Bytes(data)
|
||||
if len(content) == 0 {
|
||||
return New(nil, safe...), nil
|
||||
}
|
||||
//ignore UTF8-BOM
|
||||
if content[0] == 0xEF && content[1] == 0xBB && content[2] == 0xBF {
|
||||
content = content[3:]
|
||||
}
|
||||
option := Option{}
|
||||
if len(safe) > 0 && safe[0] {
|
||||
option.Safe = true
|
||||
}
|
||||
return doLoadContentWithOption(dataType, content, option)
|
||||
}
|
||||
|
||||
// IsValidDataType checks and returns whether given <dataType> a valid data type for loading.
|
||||
func IsValidDataType(dataType string) bool {
|
||||
if dataType == "" {
|
||||
return false
|
||||
}
|
||||
if dataType[0] == '.' {
|
||||
dataType = dataType[1:]
|
||||
}
|
||||
switch dataType {
|
||||
case "json", "js", "xml", "yaml", "yml", "toml", "ini":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func loadContentWithOption(data interface{}, option Option) (*Json, error) {
|
||||
content := gconv.Bytes(data)
|
||||
if len(content) == 0 {
|
||||
return NewWithOption(nil, option), nil
|
||||
}
|
||||
return loadContentTypeWithOption(checkDataType(content), content, option)
|
||||
}
|
||||
|
||||
func loadContentTypeWithOption(dataType string, data interface{}, option Option) (*Json, error) {
|
||||
content := gconv.Bytes(data)
|
||||
if len(content) == 0 {
|
||||
return NewWithOption(nil, option), nil
|
||||
}
|
||||
//ignore UTF8-BOM
|
||||
if content[0] == 0xEF && content[1] == 0xBB && content[2] == 0xBF {
|
||||
content = content[3:]
|
||||
}
|
||||
return doLoadContentWithOption(dataType, content, option)
|
||||
}
|
||||
|
||||
// doLoadContent creates a Json object from given content.
|
||||
// It supports data content type as follows:
|
||||
// JSON, XML, INI, YAML and TOML.
|
||||
func doLoadContent(dataType string, data []byte, safe ...bool) (*Json, error) {
|
||||
var err error
|
||||
var result interface{}
|
||||
func doLoadContentWithOption(dataType string, data []byte, option Option) (*Json, error) {
|
||||
var (
|
||||
err error
|
||||
result interface{}
|
||||
)
|
||||
if len(data) == 0 {
|
||||
return New(nil, safe...), nil
|
||||
return NewWithOption(nil, option), nil
|
||||
}
|
||||
if dataType == "" {
|
||||
dataType = checkDataType(data)
|
||||
@ -167,10 +270,9 @@ func doLoadContent(dataType string, data []byte, safe ...bool) (*Json, error) {
|
||||
return nil, err
|
||||
}
|
||||
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||
// Do not use number, it converts float64 to json.Number type,
|
||||
// which actually a string type. It causes converting issue for other data formats,
|
||||
// for example: yaml.
|
||||
//decoder.UseNumber()
|
||||
if option.StrNumber {
|
||||
decoder.UseNumber()
|
||||
}
|
||||
if err := decoder.Decode(&result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -178,48 +280,7 @@ func doLoadContent(dataType string, data []byte, safe ...bool) (*Json, error) {
|
||||
case string, []byte:
|
||||
return nil, fmt.Errorf(`json decoding failed for content: %s`, string(data))
|
||||
}
|
||||
return New(result, safe...), nil
|
||||
}
|
||||
|
||||
// LoadContent creates a Json object from given content, it checks the data type of <content>
|
||||
// automatically, supporting data content type as follows:
|
||||
// JSON, XML, INI, YAML and TOML.
|
||||
func LoadContent(data interface{}, safe ...bool) (*Json, error) {
|
||||
content := gconv.Bytes(data)
|
||||
if len(content) == 0 {
|
||||
return New(nil, safe...), nil
|
||||
}
|
||||
return LoadContentType(checkDataType(content), content, safe...)
|
||||
}
|
||||
|
||||
// LoadContentType creates a Json object from given type and content,
|
||||
// supporting data content type as follows:
|
||||
// JSON, XML, INI, YAML and TOML.
|
||||
func LoadContentType(dataType string, data interface{}, safe ...bool) (*Json, error) {
|
||||
content := gconv.Bytes(data)
|
||||
if len(content) == 0 {
|
||||
return New(nil, safe...), nil
|
||||
}
|
||||
//ignore UTF8-BOM
|
||||
if content[0] == 0xEF && content[1] == 0xBB && content[2] == 0xBF {
|
||||
content = content[3:]
|
||||
}
|
||||
return doLoadContent(dataType, content, safe...)
|
||||
}
|
||||
|
||||
// IsValidDataType checks and returns whether given <dataType> a valid data type for loading.
|
||||
func IsValidDataType(dataType string) bool {
|
||||
if dataType == "" {
|
||||
return false
|
||||
}
|
||||
if dataType[0] == '.' {
|
||||
dataType = dataType[1:]
|
||||
}
|
||||
switch dataType {
|
||||
case "json", "js", "xml", "yaml", "yml", "toml", "ini":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return NewWithOption(result, option), nil
|
||||
}
|
||||
|
||||
// checkDataType automatically checks and returns the data type for <content>.
|
||||
|
||||
@ -466,7 +466,20 @@ func Test_Basic(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_IsNil(t *testing.T) {
|
||||
func TestJson_Var(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
data := []byte("[9223372036854775807, 9223372036854775806]")
|
||||
array := gjson.New(data).Var().Array()
|
||||
t.Assert(array, []uint64{9223372036854776000, 9223372036854776000})
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
data := []byte("[9223372036854775807, 9223372036854775806]")
|
||||
array := gjson.NewWithOption(data, gjson.Option{StrNumber: true}).Var().Array()
|
||||
t.Assert(array, []uint64{9223372036854775807, 9223372036854775806})
|
||||
})
|
||||
}
|
||||
|
||||
func TestJson_IsNil(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
j := gjson.New(nil)
|
||||
t.Assert(j.IsNil(), true)
|
||||
|
||||
@ -13,7 +13,7 @@ import (
|
||||
"github.com/gogf/gf/test/gtest"
|
||||
)
|
||||
|
||||
func Test_Load_NewWithTag(t *testing.T) {
|
||||
func Test_NewWithTag(t *testing.T) {
|
||||
type User struct {
|
||||
Age int `xml:"age-xml" json:"age-json"`
|
||||
Name string `xml:"name-xml" json:"name-json"`
|
||||
@ -48,7 +48,7 @@ func Test_Load_NewWithTag(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Load_New_CustomStruct(t *testing.T) {
|
||||
func Test_New_CustomStruct(t *testing.T) {
|
||||
type Base struct {
|
||||
Id int
|
||||
}
|
||||
@ -70,7 +70,7 @@ func Test_Load_New_CustomStruct(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Load_New_HierarchicalStruct(t *testing.T) {
|
||||
func Test_New_HierarchicalStruct(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type Me struct {
|
||||
Name string `json:"name"`
|
||||
@ -97,3 +97,16 @@ func Test_Load_New_HierarchicalStruct(t *testing.T) {
|
||||
t.Assert(j.MustToJsonString(), `{"children":[{"children":null,"name":"Bean"},{"children":null,"name":"Sam"}],"name":"john","score":100}`)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_NewWithOption(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
data := []byte("[9223372036854775807, 9223372036854775806]")
|
||||
array := gjson.New(data).Array()
|
||||
t.Assert(array, []uint64{9223372036854776000, 9223372036854776000})
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
data := []byte("[9223372036854775807, 9223372036854775806]")
|
||||
array := gjson.NewWithOption(data, gjson.Option{StrNumber: true}).Array()
|
||||
t.Assert(array, []uint64{9223372036854775807, 9223372036854775806})
|
||||
})
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ func Test_GetScanDeep(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_ToScan(t *testing.T) {
|
||||
func Test_Scan1(t *testing.T) {
|
||||
type User struct {
|
||||
Name string
|
||||
Score float64
|
||||
@ -84,7 +84,7 @@ func Test_ToScan(t *testing.T) {
|
||||
j := gjson.New(`[{"name":"john", "score":"100"},{"name":"smith", "score":"60"}]`)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var users []User
|
||||
err := j.ToScan(&users)
|
||||
err := j.Scan(&users)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(users, []User{
|
||||
{
|
||||
@ -99,7 +99,7 @@ func Test_ToScan(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_ToScanDeep(t *testing.T) {
|
||||
func Test_Scan2(t *testing.T) {
|
||||
type User struct {
|
||||
Name string
|
||||
Score float64
|
||||
@ -107,7 +107,7 @@ func Test_ToScanDeep(t *testing.T) {
|
||||
j := gjson.New(`[{"name":"john", "score":"100"},{"name":"smith", "score":"60"}]`)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var users []User
|
||||
err := j.ToScanDeep(&users)
|
||||
err := j.Scan(&users)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(users, []User{
|
||||
{
|
||||
@ -122,7 +122,7 @@ func Test_ToScanDeep(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_ToStruct1(t *testing.T) {
|
||||
func Test_Struct1(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type BaseInfoItem struct {
|
||||
IdCardNumber string `db:"id_card_number" json:"idCardNumber" field:"id_card_number"`
|
||||
@ -198,12 +198,12 @@ func Test_ToStruct1(t *testing.T) {
|
||||
data := new(UserCollectionAddReq)
|
||||
j, err := gjson.LoadJson(jsonContent)
|
||||
t.Assert(err, nil)
|
||||
err = j.ToStruct(data)
|
||||
err = j.Struct(data)
|
||||
t.Assert(err, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_ToStruct(t *testing.T) {
|
||||
func Test_Struct(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
type Item struct {
|
||||
Title string `json:"title"`
|
||||
@ -231,7 +231,7 @@ func Test_ToStruct(t *testing.T) {
|
||||
t.Assert(j.GetBool("items"), false)
|
||||
t.Assert(j.GetArray("items"), nil)
|
||||
m := new(M)
|
||||
err = j.ToStruct(m)
|
||||
err = j.Struct(m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNE(m.Me, nil)
|
||||
t.Assert(m.Me["day"], "20009")
|
||||
@ -239,7 +239,7 @@ func Test_ToStruct(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Test_ToStruct_Complicated(t *testing.T) {
|
||||
func Test_Struct_Complicated(t *testing.T) {
|
||||
type CertInfo struct {
|
||||
UserRealName string `json:"userRealname,omitempty"`
|
||||
IdentType string `json:"identType,omitempty"`
|
||||
@ -290,7 +290,7 @@ func Test_ToStruct_Complicated(t *testing.T) {
|
||||
j, err := gjson.LoadContent(jsonContent)
|
||||
t.Assert(err, nil)
|
||||
var response = new(Response)
|
||||
err = j.ToStruct(response)
|
||||
err = j.Struct(response)
|
||||
t.Assert(err, nil)
|
||||
t.Assert(len(response.CertList), 3)
|
||||
t.Assert(response.CertList[0].CertID, 2023313)
|
||||
|
||||
Reference in New Issue
Block a user