add function UnmarshalValue feature for package garray/gmap/gset/gtype/gvar/gjson/gconv

This commit is contained in:
John
2020-01-20 19:56:42 +08:00
parent 7df53ff55e
commit eb6a7a4728
73 changed files with 2270 additions and 582 deletions

View File

@ -1,10 +1,32 @@
package main
import (
"fmt"
"github.com/gogf/gf/frame/g"
"os"
"github.com/gogf/gf/util/gconv"
)
func main() {
g.Dump(os.Args)
type TokenRequest struct {
Scope string
Watermark bool
Policy *g.Var
}
func main() {
// s := `
//{
// "policy": {"name":"john"},
// "scope": "pub-med-panel",
// "watermark": true
//}
//`
var t *TokenRequest
m := g.Map{
"policy": g.Map{"name": "john"},
"scope": "pub-med-panel",
"watermark": true,
}
err := gconv.Struct(m, &t)
fmt.Println(err)
fmt.Println(t.Policy)
}

View File

@ -719,3 +719,19 @@ func (a *Array) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for array.
func (a *Array) UnmarshalValue(value interface{}) error {
if a.mu == nil {
a.mu = rwmutex.New()
}
a.mu.Lock()
defer a.mu.Unlock()
switch value.(type) {
case string, []byte:
return json.Unmarshal(gconv.Bytes(value), &a.array)
default:
a.array = gconv.SliceAny(value)
}
return nil
}

View File

@ -700,3 +700,19 @@ func (a *IntArray) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for array.
func (a *IntArray) UnmarshalValue(value interface{}) error {
if a.mu == nil {
a.mu = rwmutex.New()
}
a.mu.Lock()
defer a.mu.Unlock()
switch value.(type) {
case string, []byte:
return json.Unmarshal(gconv.Bytes(value), &a.array)
default:
a.array = gconv.SliceInt(value)
}
return nil
}

View File

@ -700,3 +700,19 @@ func (a *StrArray) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for array.
func (a *StrArray) UnmarshalValue(value interface{}) error {
if a.mu == nil {
a.mu = rwmutex.New()
}
a.mu.Lock()
defer a.mu.Unlock()
switch value.(type) {
case string, []byte:
return json.Unmarshal(gconv.Bytes(value), &a.array)
default:
a.array = gconv.SliceStr(value)
}
return nil
}

View File

@ -655,10 +655,34 @@ func (a *SortedArray) UnmarshalJSON(b []byte) error {
if err := json.Unmarshal(b, &a.array); err != nil {
return err
}
if a.comparator != nil {
if a.comparator != nil && a.array != nil {
sort.Slice(a.array, func(i, j int) bool {
return a.comparator(a.array[i], a.array[j]) < 0
})
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for array.
func (a *SortedArray) UnmarshalValue(value interface{}) (err error) {
if a.mu == nil {
a.mu = rwmutex.New()
a.unique = gtype.NewBool()
// Note that the comparator is string comparator in default.
a.comparator = gutil.ComparatorString
}
a.mu.Lock()
defer a.mu.Unlock()
switch value.(type) {
case string, []byte:
err = json.Unmarshal(gconv.Bytes(value), &a.array)
default:
a.array = gconv.SliceAny(value)
}
if a.comparator != nil && a.array != nil {
sort.Slice(a.array, func(i, j int) bool {
return a.comparator(a.array[i], a.array[j]) < 0
})
}
return err
}

View File

@ -629,6 +629,30 @@ func (a *SortedIntArray) UnmarshalJSON(b []byte) error {
if err := json.Unmarshal(b, &a.array); err != nil {
return err
}
sort.Ints(a.array)
if a.array != nil {
sort.Ints(a.array)
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for array.
func (a *SortedIntArray) UnmarshalValue(value interface{}) (err error) {
if a.mu == nil {
a.mu = rwmutex.New()
a.unique = gtype.NewBool()
// Note that the comparator is string comparator in default.
a.comparator = defaultComparatorInt
}
a.mu.Lock()
defer a.mu.Unlock()
switch value.(type) {
case string, []byte:
err = json.Unmarshal(gconv.Bytes(value), &a.array)
default:
a.array = gconv.SliceInt(value)
}
if a.array != nil {
sort.Ints(a.array)
}
return err
}

View File

@ -625,6 +625,30 @@ func (a *SortedStrArray) UnmarshalJSON(b []byte) error {
if err := json.Unmarshal(b, &a.array); err != nil {
return err
}
sort.Strings(a.array)
if a.array != nil {
sort.Strings(a.array)
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for array.
func (a *SortedStrArray) UnmarshalValue(value interface{}) (err error) {
if a.mu == nil {
a.mu = rwmutex.New()
a.unique = gtype.NewBool()
// Note that the comparator is string comparator in default.
a.comparator = defaultComparatorStr
}
a.mu.Lock()
defer a.mu.Unlock()
switch value.(type) {
case string, []byte:
err = json.Unmarshal(gconv.Bytes(value), &a.array)
default:
a.array = gconv.SliceStr(value)
}
if a.array != nil {
sort.Strings(a.array)
}
return err
}

View File

@ -511,3 +511,32 @@ func TestArray_RemoveValue(t *testing.T) {
gtest.Assert(array.RemoveValue("f"), false)
})
}
func TestArray_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Array *garray.Array
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"array": []byte(`[1,2,3]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"array": g.Slice{1, 2, 3},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
})
}

View File

@ -546,3 +546,32 @@ func TestIntArray_RemoveValue(t *testing.T) {
gtest.Assert(array.Len(), 2)
})
}
func TestIntArray_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Array *garray.IntArray
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"array": []byte(`[1,2,3]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"array": g.Slice{1, 2, 3},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
})
}

View File

@ -549,3 +549,32 @@ func TestStrArray_RemoveValue(t *testing.T) {
gtest.Assert(array.RemoveValue("f"), false)
})
}
func TestStrArray_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Array *garray.StrArray
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"array": []byte(`["1","2","3"]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.SliceStr{"1", "2", "3"})
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"array": g.SliceStr{"1", "2", "3"},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.SliceStr{"1", "2", "3"})
})
}

View File

@ -649,3 +649,32 @@ func TestSortedArray_RemoveValue(t *testing.T) {
gtest.Assert(array.RemoveValue("f"), false)
})
}
func TestSortedArray_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Array *garray.SortedArray
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"array": []byte(`[2,3,1]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"array": g.Slice{2, 3, 1},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
})
}

View File

@ -530,3 +530,32 @@ func TestSortedIntArray_RemoveValue(t *testing.T) {
gtest.Assert(array.Len(), 2)
})
}
func TestSortedIntArray_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Array *garray.SortedIntArray
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"array": []byte(`[2,3,1]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"array": g.Slice{2, 3, 1},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.Slice{1, 2, 3})
})
}

View File

@ -539,3 +539,32 @@ func TestSortedStrArray_RemoveValue(t *testing.T) {
gtest.Assert(array.RemoveValue("f"), false)
})
}
func TestSortedStrArray_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Array *garray.SortedStrArray
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"array": []byte(`["1","3","2"]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.SliceStr{"1", "2", "3"})
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"array": g.SliceStr{"1", "3", "2"},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Array.Slice(), g.SliceStr{"1", "2", "3"})
})
}

View File

@ -438,3 +438,22 @@ func (l *List) UnmarshalJSON(b []byte) error {
l.PushBacks(array)
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for list.
func (l *List) UnmarshalValue(value interface{}) (err error) {
if l.mu == nil {
l.mu = rwmutex.New()
l.list = list.New()
}
l.mu.Lock()
defer l.mu.Unlock()
var array []interface{}
switch value.(type) {
case string, []byte:
err = json.Unmarshal(gconv.Bytes(value), &array)
default:
array = gconv.SliceAny(value)
}
l.PushBacks(array)
return err
}

View File

@ -632,3 +632,32 @@ func TestList_Json(t *testing.T) {
gtest.Assert(l.FrontAll(), a)
})
}
func TestList_UnmarshalValue(t *testing.T) {
type T struct {
Name string
List *List
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"list": []byte(`[1,2,3]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.List.FrontAll(), []interface{}{1, 2, 3})
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"list": []interface{}{1, 2, 3},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.List.FrontAll(), []interface{}{1, 2, 3})
})
}

View File

@ -436,3 +436,17 @@ func (m *AnyAnyMap) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for map.
func (m *AnyAnyMap) UnmarshalValue(value interface{}) (err error) {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[interface{}]interface{})
}
m.mu.Lock()
defer m.mu.Unlock()
for k, v := range gconv.Map(value) {
m.data[k] = v
}
return
}

View File

@ -432,3 +432,22 @@ func (m *IntAnyMap) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for map.
func (m *IntAnyMap) UnmarshalValue(value interface{}) (err error) {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[int]interface{})
}
m.mu.Lock()
defer m.mu.Unlock()
switch value.(type) {
case string, []byte:
return json.Unmarshal(gconv.Bytes(value), &m.data)
default:
for k, v := range gconv.Map(value) {
m.data[gconv.Int(k)] = v
}
}
return
}

View File

@ -409,3 +409,22 @@ func (m *IntIntMap) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for map.
func (m *IntIntMap) UnmarshalValue(value interface{}) (err error) {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[int]int)
}
m.mu.Lock()
defer m.mu.Unlock()
switch value.(type) {
case string, []byte:
return json.Unmarshal(gconv.Bytes(value), &m.data)
default:
for k, v := range gconv.Map(value) {
m.data[gconv.Int(k)] = gconv.Int(v)
}
}
return
}

View File

@ -410,3 +410,22 @@ func (m *IntStrMap) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for map.
func (m *IntStrMap) UnmarshalValue(value interface{}) (err error) {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[int]string)
}
m.mu.Lock()
defer m.mu.Unlock()
switch value.(type) {
case string, []byte:
return json.Unmarshal(gconv.Bytes(value), &m.data)
default:
for k, v := range gconv.Map(value) {
m.data[gconv.Int(k)] = gconv.String(v)
}
}
return
}

View File

@ -428,3 +428,15 @@ func (m *StrAnyMap) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for map.
func (m *StrAnyMap) UnmarshalValue(value interface{}) (err error) {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[string]interface{})
}
m.mu.Lock()
defer m.mu.Unlock()
m.data = gconv.Map(value)
return
}

View File

@ -411,3 +411,22 @@ func (m *StrIntMap) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for map.
func (m *StrIntMap) UnmarshalValue(value interface{}) (err error) {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[string]int)
}
m.mu.Lock()
defer m.mu.Unlock()
switch value.(type) {
case string, []byte:
return json.Unmarshal(gconv.Bytes(value), &m.data)
default:
for k, v := range gconv.Map(value) {
m.data[k] = gconv.Int(v)
}
}
return
}

View File

@ -9,6 +9,7 @@ package gmap
import (
"encoding/json"
"github.com/gogf/gf/util/gconv"
"github.com/gogf/gf/internal/empty"
@ -412,3 +413,14 @@ func (m *StrStrMap) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for map.
func (m *StrStrMap) UnmarshalValue(value interface{}) (err error) {
if m.mu == nil {
m.mu = rwmutex.New()
}
m.mu.Lock()
defer m.mu.Unlock()
m.data = gconv.MapStrStr(value)
return
}

View File

@ -491,3 +491,22 @@ func (m *ListMap) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for map.
func (m *ListMap) UnmarshalValue(value interface{}) (err error) {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[interface{}]*glist.Element)
m.list = glist.New()
}
m.mu.Lock()
defer m.mu.Unlock()
for k, v := range gconv.Map(value) {
if e, ok := m.data[k]; !ok {
m.data[k] = m.list.PushBack(&gListMapNode{k, v})
} else {
e.Value = &gListMapNode{k, v}
}
}
return
}

View File

@ -275,3 +275,39 @@ func Test_AnyAnyMap_Pops(t *testing.T) {
gtest.Assert(vArray.Unique().Len(), 3)
})
}
func TestAnyAnyMap_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Map *gmap.Map
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"k1":"v1","k2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.Map{
"k1": "v1",
"k2": "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
})
}

View File

@ -10,6 +10,7 @@ import (
"encoding/json"
"github.com/gogf/gf/container/garray"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/util/gconv"
"testing"
"github.com/gogf/gf/container/gmap"
@ -257,3 +258,39 @@ func Test_IntAnyMap_Pops(t *testing.T) {
gtest.Assert(vArray.Unique().Len(), 3)
})
}
func TestIntAnyMap_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Map *gmap.IntAnyMap
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"1":"v1","2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get(1), "v1")
gtest.Assert(t.Map.Get(2), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.MapIntAny{
1: "v1",
2: "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get(1), "v1")
gtest.Assert(t.Map.Get(2), "v2")
})
}

View File

@ -10,6 +10,7 @@ import (
"encoding/json"
"github.com/gogf/gf/container/garray"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/util/gconv"
"testing"
"github.com/gogf/gf/container/gmap"
@ -260,3 +261,39 @@ func Test_IntIntMap_Pops(t *testing.T) {
gtest.Assert(vArray.Unique().Len(), 3)
})
}
func TestIntIntMap_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Map *gmap.IntIntMap
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"1":1,"2":2}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get(1), "1")
gtest.Assert(t.Map.Get(2), "2")
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.MapIntAny{
1: 1,
2: 2,
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get(1), "1")
gtest.Assert(t.Map.Get(2), "2")
})
}

View File

@ -10,6 +10,7 @@ import (
"encoding/json"
"github.com/gogf/gf/container/garray"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/util/gconv"
"testing"
"github.com/gogf/gf/container/gmap"
@ -261,3 +262,39 @@ func Test_IntStrMap_Pops(t *testing.T) {
gtest.Assert(vArray.Unique().Len(), 3)
})
}
func TestIntStrMap_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Map *gmap.IntStrMap
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"1":"v1","2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get(1), "v1")
gtest.Assert(t.Map.Get(2), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.MapIntAny{
1: "v1",
2: "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get(1), "v1")
gtest.Assert(t.Map.Get(2), "v2")
})
}

View File

@ -231,3 +231,39 @@ func Test_ListMap_Pops(t *testing.T) {
gtest.Assert(vArray.Unique().Len(), 3)
})
}
func TestListMap_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Map *gmap.ListMap
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"1":"v1","2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("1"), "v1")
gtest.Assert(t.Map.Get("2"), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.MapIntAny{
1: "v1",
2: "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("1"), "v1")
gtest.Assert(t.Map.Get("2"), "v2")
})
}

View File

@ -10,6 +10,7 @@ import (
"encoding/json"
"github.com/gogf/gf/container/garray"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/util/gconv"
"testing"
"github.com/gogf/gf/container/gmap"
@ -269,3 +270,39 @@ func Test_StrAnyMap_Pops(t *testing.T) {
gtest.Assert(vArray.Unique().Len(), 3)
})
}
func TestStrAnyMap_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Map *gmap.StrAnyMap
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"k1":"v1","k2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.Map{
"k1": "v1",
"k2": "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
})
}

View File

@ -10,6 +10,7 @@ import (
"encoding/json"
"github.com/gogf/gf/container/garray"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/util/gconv"
"testing"
"github.com/gogf/gf/container/gmap"
@ -272,3 +273,39 @@ func Test_StrIntMap_Pops(t *testing.T) {
gtest.Assert(vArray.Unique().Len(), 3)
})
}
func TestStrIntMap_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Map *gmap.StrIntMap
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"k1":1,"k2":2}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), 1)
gtest.Assert(t.Map.Get("k2"), 2)
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.Map{
"k1": 1,
"k2": 2,
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), 1)
gtest.Assert(t.Map.Get("k2"), 2)
})
}

View File

@ -10,6 +10,7 @@ import (
"encoding/json"
"github.com/gogf/gf/container/garray"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/util/gconv"
"testing"
"github.com/gogf/gf/container/gmap"
@ -269,3 +270,39 @@ func Test_StrStrMap_Pops(t *testing.T) {
gtest.Assert(vArray.Unique().Len(), 3)
})
}
func TestStrStrMap_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Map *gmap.StrStrMap
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"k1":"v1","k2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.Map{
"k1": "v1",
"k2": "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
})
}

View File

@ -148,3 +148,39 @@ func Test_TreeMap_Json(t *testing.T) {
gtest.Assert(m.Get("k2"), data["k2"])
})
}
func TestTreeMap_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Map *gmap.TreeMap
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": []byte(`{"k1":"v1","k2":"v2"}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"map": g.Map{
"k1": "v1",
"k2": "v2",
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Map.Size(), 2)
gtest.Assert(t.Map.Get("k1"), "v1")
gtest.Assert(t.Map.Get("k2"), "v2")
})
}

View File

@ -430,3 +430,24 @@ func (set *Set) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for set.
func (set *Set) UnmarshalValue(value interface{}) (err error) {
if set.mu == nil {
set.mu = rwmutex.New()
set.data = make(map[interface{}]struct{})
}
set.mu.Lock()
defer set.mu.Unlock()
var array []interface{}
switch value.(type) {
case string, []byte:
err = json.Unmarshal(gconv.Bytes(value), &array)
default:
array = gconv.SliceAny(value)
}
for _, v := range array {
set.data[v] = struct{}{}
}
return
}

View File

@ -401,3 +401,24 @@ func (set *IntSet) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for set.
func (set *IntSet) UnmarshalValue(value interface{}) (err error) {
if set.mu == nil {
set.mu = rwmutex.New()
set.data = make(map[int]struct{})
}
set.mu.Lock()
defer set.mu.Unlock()
var array []int
switch value.(type) {
case string, []byte:
err = json.Unmarshal(gconv.Bytes(value), &array)
default:
array = gconv.SliceInt(value)
}
for _, v := range array {
set.data[v] = struct{}{}
}
return
}

View File

@ -417,3 +417,24 @@ func (set *StrSet) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for set.
func (set *StrSet) UnmarshalValue(value interface{}) (err error) {
if set.mu == nil {
set.mu = rwmutex.New()
set.data = make(map[string]struct{})
}
set.mu.Lock()
defer set.mu.Unlock()
var array []string
switch value.(type) {
case string, []byte:
err = json.Unmarshal(gconv.Bytes(value), &array)
default:
array = gconv.SliceStr(value)
}
for _, v := range array {
set.data[v] = struct{}{}
}
return
}

View File

@ -10,6 +10,8 @@ package gset_test
import (
"encoding/json"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/util/gconv"
"strings"
"github.com/gogf/gf/container/garray"
@ -361,3 +363,40 @@ func TestSet_AddIfNotExistFunc(t *testing.T) {
gtest.Assert(s.Contains(4), false)
})
}
func TestSet_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Set *gset.Set
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"set": []byte(`["k1","k2","k3"]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Set.Size(), 3)
gtest.Assert(t.Set.Contains("k1"), true)
gtest.Assert(t.Set.Contains("k2"), true)
gtest.Assert(t.Set.Contains("k3"), true)
gtest.Assert(t.Set.Contains("k4"), false)
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"set": g.Slice{"k1", "k2", "k3"},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Set.Size(), 3)
gtest.Assert(t.Set.Contains("k1"), true)
gtest.Assert(t.Set.Contains("k2"), true)
gtest.Assert(t.Set.Contains("k3"), true)
gtest.Assert(t.Set.Contains("k4"), false)
})
}

View File

@ -10,6 +10,8 @@ package gset_test
import (
"encoding/json"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/util/gconv"
"strings"
"testing"
@ -324,3 +326,40 @@ func TestIntSet_AddIfNotExistFunc(t *testing.T) {
gtest.Assert(s.Contains(4), false)
})
}
func TestIntSet_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Set *gset.IntSet
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"set": []byte(`[1,2,3]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Set.Size(), 3)
gtest.Assert(t.Set.Contains(1), true)
gtest.Assert(t.Set.Contains(2), true)
gtest.Assert(t.Set.Contains(3), true)
gtest.Assert(t.Set.Contains(4), false)
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"set": g.Slice{1, 2, 3},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Set.Size(), 3)
gtest.Assert(t.Set.Contains(1), true)
gtest.Assert(t.Set.Contains(2), true)
gtest.Assert(t.Set.Contains(3), true)
gtest.Assert(t.Set.Contains(4), false)
})
}

View File

@ -10,6 +10,8 @@ package gset_test
import (
"encoding/json"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/util/gconv"
"strings"
"testing"
@ -360,3 +362,40 @@ func TestStrSet_AddIfNotExistFunc(t *testing.T) {
gtest.Assert(s.Contains("4"), false)
})
}
func TestStrSet_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Set *gset.StrSet
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"set": []byte(`["1","2","3"]`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Set.Size(), 3)
gtest.Assert(t.Set.Contains("1"), true)
gtest.Assert(t.Set.Contains("2"), true)
gtest.Assert(t.Set.Contains("3"), true)
gtest.Assert(t.Set.Contains("4"), false)
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"set": g.SliceStr{"1", "2", "3"},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Set.Size(), 3)
gtest.Assert(t.Set.Contains("1"), true)
gtest.Assert(t.Set.Contains("2"), true)
gtest.Assert(t.Set.Contains("3"), true)
gtest.Assert(t.Set.Contains("4"), false)
})
}

View File

@ -942,3 +942,17 @@ func (tree *RedBlackTree) UnmarshalJSON(b []byte) error {
}
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for map.
func (tree *RedBlackTree) UnmarshalValue(value interface{}) (err error) {
if tree.mu == nil {
tree.mu = rwmutex.New()
tree.comparator = gutil.ComparatorString
}
tree.mu.Lock()
defer tree.mu.Unlock()
for k, v := range gconv.Map(value) {
tree.doSet(k, v)
}
return
}

View File

@ -90,3 +90,9 @@ func (v *Bool) UnmarshalJSON(b []byte) error {
v.Set(gconv.Bool(bytes.Trim(b, `"`)))
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for <v>.
func (v *Bool) UnmarshalValue(value interface{}) error {
v.Set(gconv.Bool(value))
return nil
}

View File

@ -68,3 +68,9 @@ func (v *Byte) UnmarshalJSON(b []byte) error {
v.Set(gconv.Uint8(gconv.UnsafeBytesToStr(b)))
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for <v>.
func (v *Byte) UnmarshalValue(value interface{}) error {
v.Set(gconv.Byte(value))
return nil
}

View File

@ -72,3 +72,9 @@ func (v *Bytes) UnmarshalJSON(b []byte) error {
v.Set(src[:n])
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for <v>.
func (v *Bytes) UnmarshalValue(value interface{}) error {
v.Set(gconv.Bytes(value))
return nil
}

View File

@ -81,3 +81,9 @@ func (v *Float32) UnmarshalJSON(b []byte) error {
v.Set(gconv.Float32(gconv.UnsafeBytesToStr(b)))
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for <v>.
func (v *Float32) UnmarshalValue(value interface{}) error {
v.Set(gconv.Float32(value))
return nil
}

View File

@ -81,3 +81,9 @@ func (v *Float64) UnmarshalJSON(b []byte) error {
v.Set(gconv.Float64(gconv.UnsafeBytesToStr(b)))
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for <v>.
func (v *Float64) UnmarshalValue(value interface{}) error {
v.Set(gconv.Float64(value))
return nil
}

View File

@ -68,3 +68,9 @@ func (v *Int) UnmarshalJSON(b []byte) error {
v.Set(gconv.Int(gconv.UnsafeBytesToStr(b)))
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for <v>.
func (v *Int) UnmarshalValue(value interface{}) error {
v.Set(gconv.Int(value))
return nil
}

View File

@ -68,3 +68,9 @@ func (v *Int32) UnmarshalJSON(b []byte) error {
v.Set(gconv.Int32(gconv.UnsafeBytesToStr(b)))
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for <v>.
func (v *Int32) UnmarshalValue(value interface{}) error {
v.Set(gconv.Int32(value))
return nil
}

View File

@ -68,3 +68,9 @@ func (v *Int64) UnmarshalJSON(b []byte) error {
v.Set(gconv.Int64(gconv.UnsafeBytesToStr(b)))
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for <v>.
func (v *Int64) UnmarshalValue(value interface{}) error {
v.Set(gconv.Int64(value))
return nil
}

View File

@ -65,3 +65,9 @@ func (v *Interface) UnmarshalJSON(b []byte) error {
v.Set(i)
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for <v>.
func (v *Interface) UnmarshalValue(value interface{}) error {
v.Set(value)
return nil
}

View File

@ -63,3 +63,9 @@ func (v *String) UnmarshalJSON(b []byte) error {
v.Set(gconv.UnsafeBytesToStr(bytes.Trim(b, `"`)))
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for <v>.
func (v *String) UnmarshalValue(value interface{}) error {
v.Set(gconv.String(value))
return nil
}

View File

@ -68,3 +68,9 @@ func (v *Uint) UnmarshalJSON(b []byte) error {
v.Set(gconv.Uint(gconv.UnsafeBytesToStr(b)))
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for <v>.
func (v *Uint) UnmarshalValue(value interface{}) error {
v.Set(gconv.Uint(value))
return nil
}

View File

@ -68,3 +68,9 @@ func (v *Uint32) UnmarshalJSON(b []byte) error {
v.Set(gconv.Uint32(gconv.UnsafeBytesToStr(b)))
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for <v>.
func (v *Uint32) UnmarshalValue(value interface{}) error {
v.Set(gconv.Uint32(value))
return nil
}

View File

@ -68,3 +68,9 @@ func (v *Uint64) UnmarshalJSON(b []byte) error {
v.Set(gconv.Uint64(gconv.UnsafeBytesToStr(b)))
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for <v>.
func (v *Uint64) UnmarshalValue(value interface{}) error {
v.Set(gconv.Uint64(value))
return nil
}

View File

@ -0,0 +1,125 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"github.com/gogf/gf/util/gconv"
"testing"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
)
func Test_Bool(t *testing.T) {
gtest.Case(t, func() {
i := gtype.NewBool(true)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(false), true)
gtest.AssertEQ(iClone.Val(), false)
i1 := gtype.NewBool(false)
iClone1 := i1.Clone()
gtest.AssertEQ(iClone1.Set(true), false)
gtest.AssertEQ(iClone1.Val(), true)
//空参测试
i2 := gtype.NewBool()
gtest.AssertEQ(i2.Val(), false)
})
}
func Test_Bool_JSON(t *testing.T) {
// Marshal
gtest.Case(t, func() {
i := gtype.NewBool(true)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
})
gtest.Case(t, func() {
i := gtype.NewBool(false)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
var err error
i := gtype.NewBool()
err = json.Unmarshal([]byte("true"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), true)
err = json.Unmarshal([]byte("false"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), false)
err = json.Unmarshal([]byte("1"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), true)
err = json.Unmarshal([]byte("0"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), false)
})
gtest.Case(t, func() {
i := gtype.NewBool(true)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewBool()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i.Val())
})
gtest.Case(t, func() {
i := gtype.NewBool(false)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewBool()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i.Val())
})
}
func Test_Bool_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gtype.Bool
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "true",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), true)
})
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "false",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), false)
})
}

View File

@ -0,0 +1,77 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"github.com/gogf/gf/util/gconv"
"sync"
"testing"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
)
func Test_Byte(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 127
i := gtype.NewByte(byte(0))
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(byte(1)), byte(0))
gtest.AssertEQ(iClone.Val(), byte(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(byte(addTimes), i.Val())
//空参测试
i1 := gtype.NewByte()
gtest.AssertEQ(i1.Val(), byte(0))
})
}
func Test_Byte_JSON(t *testing.T) {
gtest.Case(t, func() {
i := gtype.NewByte(49)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
var err error
i := gtype.NewByte()
err = json.Unmarshal([]byte("49"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), "49")
})
}
func Test_Byte_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gtype.Byte
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "2",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "2")
})
}

View File

@ -0,0 +1,63 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"github.com/gogf/gf/util/gconv"
"testing"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
)
func Test_Bytes(t *testing.T) {
gtest.Case(t, func() {
i := gtype.NewBytes([]byte("abc"))
iClone := i.Clone()
gtest.AssertEQ(iClone.Set([]byte("123")), []byte("abc"))
gtest.AssertEQ(iClone.Val(), []byte("123"))
//空参测试
i1 := gtype.NewBytes()
gtest.AssertEQ(i1.Val(), nil)
})
}
func Test_Bytes_JSON(t *testing.T) {
gtest.Case(t, func() {
b := []byte("i love gf")
i := gtype.NewBytes(b)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewBytes()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), b)
})
}
func Test_Bytes_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gtype.Bytes
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
})
}

View File

@ -0,0 +1,64 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/util/gconv"
"math"
"testing"
)
func Test_Float32(t *testing.T) {
gtest.Case(t, func() {
i := gtype.NewFloat32(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(0.1), float32(0))
gtest.AssertEQ(iClone.Val(), float32(0.1))
//空参测试
i1 := gtype.NewFloat32()
gtest.AssertEQ(i1.Val(), float32(0))
})
}
func Test_Float32_JSON(t *testing.T) {
gtest.Case(t, func() {
v := float32(math.MaxFloat32)
i := gtype.NewFloat32(v)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewFloat32()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), v)
})
}
func Test_Float32_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gtype.Float32
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123.456",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123.456")
})
}

View File

@ -0,0 +1,62 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/util/gconv"
"math"
"testing"
)
func Test_Float64(t *testing.T) {
gtest.Case(t, func() {
i := gtype.NewFloat64(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(0.1), float64(0))
gtest.AssertEQ(iClone.Val(), float64(0.1))
//空参测试
i1 := gtype.NewFloat64()
gtest.AssertEQ(i1.Val(), float64(0))
})
}
func Test_Float64_JSON(t *testing.T) {
gtest.Case(t, func() {
v := math.MaxFloat64
i := gtype.NewFloat64(v)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewFloat64()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), v)
})
}
func Test_Float64_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gtype.Float64
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123.456",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123.456")
})
}

View File

@ -0,0 +1,75 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/util/gconv"
"math"
"sync"
"testing"
)
func Test_Int32(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewInt32(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), int32(0))
gtest.AssertEQ(iClone.Val(), int32(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(int32(addTimes), i.Val())
//空参测试
i1 := gtype.NewInt32()
gtest.AssertEQ(i1.Val(), int32(0))
})
}
func Test_Int32_JSON(t *testing.T) {
gtest.Case(t, func() {
v := int32(math.MaxInt32)
i := gtype.NewInt32(v)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewInt32()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), v)
})
}
func Test_Int32_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gtype.Int32
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
})
}

View File

@ -0,0 +1,74 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/util/gconv"
"math"
"sync"
"testing"
)
func Test_Int64(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewInt64(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), int64(0))
gtest.AssertEQ(iClone.Val(), int64(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(int64(addTimes), i.Val())
//空参测试
i1 := gtype.NewInt64()
gtest.AssertEQ(i1.Val(), int64(0))
})
}
func Test_Int64_JSON(t *testing.T) {
gtest.Case(t, func() {
i := gtype.NewInt64(math.MaxInt64)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewInt64()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i)
})
}
func Test_Int64_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gtype.Int64
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
})
}

View File

@ -0,0 +1,74 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/util/gconv"
"sync"
"testing"
)
func Test_Int(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewInt(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), 0)
gtest.AssertEQ(iClone.Val(), 1)
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(addTimes, i.Val())
//空参测试
i1 := gtype.NewInt()
gtest.AssertEQ(i1.Val(), 0)
})
}
func Test_Int_JSON(t *testing.T) {
gtest.Case(t, func() {
v := 666
i := gtype.NewInt(v)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewInt()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), v)
})
}
func Test_Int_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gtype.Int
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
})
}

View File

@ -0,0 +1,64 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/util/gconv"
"testing"
)
func Test_Interface(t *testing.T) {
gtest.Case(t, func() {
t := Temp{Name: "gf", Age: 18}
t1 := Temp{Name: "gf", Age: 19}
i := gtype.New(t)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(t1), t)
gtest.AssertEQ(iClone.Val().(Temp), t1)
//空参测试
i1 := gtype.New()
gtest.AssertEQ(i1.Val(), nil)
})
}
func Test_Interface_JSON(t *testing.T) {
gtest.Case(t, func() {
s := "i love gf"
i := gtype.New(s)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.New()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), s)
})
}
func Test_Interface_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gtype.Interface
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
})
}

View File

@ -0,0 +1,62 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/util/gconv"
"testing"
)
func Test_String(t *testing.T) {
gtest.Case(t, func() {
i := gtype.NewString("abc")
iClone := i.Clone()
gtest.AssertEQ(iClone.Set("123"), "abc")
gtest.AssertEQ(iClone.Val(), "123")
//空参测试
i1 := gtype.NewString()
gtest.AssertEQ(i1.Val(), "")
})
}
func Test_String_JSON(t *testing.T) {
gtest.Case(t, func() {
s := "i love gf"
i1 := gtype.NewString(s)
b1, err1 := json.Marshal(i1)
b2, err2 := json.Marshal(i1.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewString()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), s)
})
}
func Test_String_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gtype.String
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
})
}

View File

@ -1,528 +0,0 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"math"
"sync"
"testing"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
)
type Temp struct {
Name string
Age int
}
func Test_Bool(t *testing.T) {
gtest.Case(t, func() {
i := gtype.NewBool(true)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(false), true)
gtest.AssertEQ(iClone.Val(), false)
i1 := gtype.NewBool(false)
iClone1 := i1.Clone()
gtest.AssertEQ(iClone1.Set(true), false)
gtest.AssertEQ(iClone1.Val(), true)
//空参测试
i2 := gtype.NewBool()
gtest.AssertEQ(i2.Val(), false)
})
// Marshal
gtest.Case(t, func() {
i := gtype.NewBool(true)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
})
gtest.Case(t, func() {
i := gtype.NewBool(false)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
var err error
i := gtype.NewBool()
err = json.Unmarshal([]byte("true"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), true)
err = json.Unmarshal([]byte("false"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), false)
err = json.Unmarshal([]byte("1"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), true)
err = json.Unmarshal([]byte("0"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), false)
})
gtest.Case(t, func() {
i := gtype.NewBool(true)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewBool()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i.Val())
})
gtest.Case(t, func() {
i := gtype.NewBool(false)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewBool()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i.Val())
})
}
func Test_Byte(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 127
i := gtype.NewByte(byte(0))
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(byte(1)), byte(0))
gtest.AssertEQ(iClone.Val(), byte(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(byte(addTimes), i.Val())
//空参测试
i1 := gtype.NewByte()
gtest.AssertEQ(i1.Val(), byte(0))
})
gtest.Case(t, func() {
i := gtype.NewByte(49)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
var err error
i := gtype.NewByte()
err = json.Unmarshal([]byte("49"), &i)
gtest.Assert(err, nil)
gtest.Assert(i.Val(), "49")
})
}
func Test_Bytes(t *testing.T) {
gtest.Case(t, func() {
i := gtype.NewBytes([]byte("abc"))
iClone := i.Clone()
gtest.AssertEQ(iClone.Set([]byte("123")), []byte("abc"))
gtest.AssertEQ(iClone.Val(), []byte("123"))
//空参测试
i1 := gtype.NewBytes()
gtest.AssertEQ(i1.Val(), nil)
})
gtest.Case(t, func() {
b := []byte("i love gf")
i := gtype.NewBytes(b)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewBytes()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), b)
})
}
func Test_String(t *testing.T) {
gtest.Case(t, func() {
i := gtype.NewString("abc")
iClone := i.Clone()
gtest.AssertEQ(iClone.Set("123"), "abc")
gtest.AssertEQ(iClone.Val(), "123")
//空参测试
i1 := gtype.NewString()
gtest.AssertEQ(i1.Val(), "")
})
gtest.Case(t, func() {
s := "i love gf"
i1 := gtype.NewString(s)
b1, err1 := json.Marshal(i1)
b2, err2 := json.Marshal(i1.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewString()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), s)
})
}
func Test_Interface(t *testing.T) {
gtest.Case(t, func() {
t := Temp{Name: "gf", Age: 18}
t1 := Temp{Name: "gf", Age: 19}
i := gtype.New(t)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(t1), t)
gtest.AssertEQ(iClone.Val().(Temp), t1)
//空参测试
i1 := gtype.New()
gtest.AssertEQ(i1.Val(), nil)
})
gtest.Case(t, func() {
s := "i love gf"
i := gtype.New(s)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.New()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), s)
})
}
func Test_Float32(t *testing.T) {
gtest.Case(t, func() {
//var wg sync.WaitGroup
//addTimes := 100
i := gtype.NewFloat32(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(0.1), float32(0))
gtest.AssertEQ(iClone.Val(), float32(0.1))
// for index := 0; index < addTimes; index++ {
// wg.Add(1)
// go func() {
// defer wg.Done()
// i.Add(0.2)
// fmt.Println(i.Val())
// }()
// }
// wg.Wait()
// gtest.AssertEQ(100.0, i.Val())
//空参测试
i1 := gtype.NewFloat32()
gtest.AssertEQ(i1.Val(), float32(0))
})
gtest.Case(t, func() {
v := float32(math.MaxFloat32)
i := gtype.NewFloat32(v)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewFloat32()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), v)
})
}
func Test_Float64(t *testing.T) {
gtest.Case(t, func() {
//var wg sync.WaitGroup
//addTimes := 100
i := gtype.NewFloat64(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(0.1), float64(0))
gtest.AssertEQ(iClone.Val(), float64(0.1))
// for index := 0; index < addTimes; index++ {
// wg.Add(1)
// go func() {
// defer wg.Done()
// i.Add(0.1)
// fmt.Println(i.Val())
// }()
// }
// wg.Wait()
// gtest.AssertEQ(100.0, i.Val())
//空参测试
i1 := gtype.NewFloat64()
gtest.AssertEQ(i1.Val(), float64(0))
})
gtest.Case(t, func() {
v := math.MaxFloat64
i := gtype.NewFloat64(v)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewFloat64()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), v)
})
}
func Test_Int(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewInt(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), 0)
gtest.AssertEQ(iClone.Val(), 1)
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(addTimes, i.Val())
//空参测试
i1 := gtype.NewInt()
gtest.AssertEQ(i1.Val(), 0)
})
gtest.Case(t, func() {
v := 666
i := gtype.NewInt(v)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewInt()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), v)
})
}
func Test_Int32(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewInt32(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), int32(0))
gtest.AssertEQ(iClone.Val(), int32(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(int32(addTimes), i.Val())
//空参测试
i1 := gtype.NewInt32()
gtest.AssertEQ(i1.Val(), int32(0))
})
gtest.Case(t, func() {
v := int32(math.MaxInt32)
i := gtype.NewInt32(v)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewInt32()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), v)
})
}
func Test_Int64(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewInt64(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), int64(0))
gtest.AssertEQ(iClone.Val(), int64(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(int64(addTimes), i.Val())
//空参测试
i1 := gtype.NewInt64()
gtest.AssertEQ(i1.Val(), int64(0))
})
gtest.Case(t, func() {
i := gtype.NewInt64(math.MaxInt64)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewInt64()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i)
})
}
func Test_Uint(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewUint(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), uint(0))
gtest.AssertEQ(iClone.Val(), uint(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(uint(addTimes), i.Val())
//空参测试
i1 := gtype.NewUint()
gtest.AssertEQ(i1.Val(), uint(0))
})
gtest.Case(t, func() {
i := gtype.NewUint(666)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewUint()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i)
})
}
func Test_Uint32(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewUint32(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), uint32(0))
gtest.AssertEQ(iClone.Val(), uint32(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(uint32(addTimes), i.Val())
//空参测试
i1 := gtype.NewUint32()
gtest.AssertEQ(i1.Val(), uint32(0))
})
gtest.Case(t, func() {
i := gtype.NewUint32(math.MaxUint32)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewUint32()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i)
})
}
func Test_Uint64(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewUint64(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), uint64(0))
gtest.AssertEQ(iClone.Val(), uint64(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(uint64(addTimes), i.Val())
//空参测试
i1 := gtype.NewUint64()
gtest.AssertEQ(i1.Val(), uint64(0))
})
gtest.Case(t, func() {
i := gtype.NewUint64(math.MaxUint64)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewUint64()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i)
})
}

View File

@ -0,0 +1,74 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/util/gconv"
"math"
"sync"
"testing"
)
func Test_Uint32(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewUint32(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), uint32(0))
gtest.AssertEQ(iClone.Val(), uint32(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(uint32(addTimes), i.Val())
//空参测试
i1 := gtype.NewUint32()
gtest.AssertEQ(i1.Val(), uint32(0))
})
}
func Test_Uint32_JSON(t *testing.T) {
gtest.Case(t, func() {
i := gtype.NewUint32(math.MaxUint32)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewUint32()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i)
})
}
func Test_Uint32_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gtype.Uint32
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
})
}

View File

@ -0,0 +1,79 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"github.com/gogf/gf/util/gconv"
"math"
"sync"
"testing"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
)
type Temp struct {
Name string
Age int
}
func Test_Uint64(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewUint64(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), uint64(0))
gtest.AssertEQ(iClone.Val(), uint64(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(uint64(addTimes), i.Val())
//空参测试
i1 := gtype.NewUint64()
gtest.AssertEQ(i1.Val(), uint64(0))
})
}
func Test_Uint64_JSON(t *testing.T) {
gtest.Case(t, func() {
i := gtype.NewUint64(math.MaxUint64)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewUint64()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i)
})
}
func Test_Uint64_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gtype.Uint64
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
})
}

View File

@ -0,0 +1,73 @@
// Copyright 2018 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 gtype_test
import (
"encoding/json"
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/util/gconv"
"sync"
"testing"
)
func Test_Uint(t *testing.T) {
gtest.Case(t, func() {
var wg sync.WaitGroup
addTimes := 1000
i := gtype.NewUint(0)
iClone := i.Clone()
gtest.AssertEQ(iClone.Set(1), uint(0))
gtest.AssertEQ(iClone.Val(), uint(1))
for index := 0; index < addTimes; index++ {
wg.Add(1)
go func() {
defer wg.Done()
i.Add(1)
}()
}
wg.Wait()
gtest.AssertEQ(uint(addTimes), i.Val())
//空参测试
i1 := gtype.NewUint()
gtest.AssertEQ(i1.Val(), uint(0))
})
}
func Test_Uint_JSON(t *testing.T) {
gtest.Case(t, func() {
i := gtype.NewUint(666)
b1, err1 := json.Marshal(i)
b2, err2 := json.Marshal(i.Val())
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(b1, b2)
i2 := gtype.NewUint()
err := json.Unmarshal(b2, &i2)
gtest.Assert(err, nil)
gtest.Assert(i2.Val(), i)
})
}
func Test_Uint_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gtype.Uint
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "123",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.Val(), "123")
})
}

View File

@ -335,3 +335,9 @@ func (v *Var) UnmarshalJSON(b []byte) error {
v.Set(i)
return nil
}
// UnmarshalValue is an interface implement which sets any type of value for Var.
func (v *Var) UnmarshalValue(value interface{}) error {
v.Set(value)
return nil
}

View File

@ -10,6 +10,7 @@ import (
"bytes"
"encoding/binary"
"encoding/json"
"github.com/gogf/gf/util/gconv"
"math"
"testing"
"time"
@ -378,3 +379,20 @@ func Test_Json(t *testing.T) {
gtest.Assert(v.String(), s)
})
}
func Test_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Var *gvar.Var
}
gtest.Case(t, func() {
var t *T
err := gconv.Struct(map[string]interface{}{
"name": "john",
"var": "v",
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Var.String(), "v")
})
}

View File

@ -30,11 +30,6 @@ type Json struct {
vc bool // Violence Check(false in default), which is used to access data when the hierarchical data key contains separator char.
}
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
func (j *Json) MarshalJSON() ([]byte, error) {
return j.ToJson()
}
// setValue sets <value> to <j> by <pattern>.
// Note:
// 1. If value is nil and removed is true, means deleting this value;

View File

@ -0,0 +1,31 @@
// Copyright 2019 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
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
func (j *Json) MarshalJSON() ([]byte, error) {
return j.ToJson()
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (j *Json) UnmarshalJSON(b []byte) error {
r, err := LoadContent(b)
if r != nil {
// Value copy.
*j = *r
}
return err
}
// UnmarshalValue is an interface implement which sets any type of value for Json.
func (j *Json) UnmarshalValue(value interface{}) error {
if r := New(value); r != nil {
// Value copy.
*j = *r
}
return nil
}

View File

@ -0,0 +1,72 @@
// 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_test
import (
"encoding/json"
"github.com/gogf/gf/util/gconv"
"testing"
"github.com/gogf/gf/encoding/gjson"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/test/gtest"
)
func TestJson_UnmarshalJSON(t *testing.T) {
data := []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`)
gtest.Case(t, func() {
j := gjson.New(nil)
err := json.Unmarshal(data, j)
gtest.Assert(err, nil)
gtest.Assert(j.Get("n"), "123456789")
gtest.Assert(j.Get("m"), g.Map{"k": "v"})
gtest.Assert(j.Get("m.k"), "v")
gtest.Assert(j.Get("a"), g.Slice{1, 2, 3})
gtest.Assert(j.Get("a.1"), 2)
})
}
func TestJson_UnmarshalValue(t *testing.T) {
type T struct {
Name string
Json *gjson.Json
}
// JSON
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"json": []byte(`{"n":123456789, "m":{"k":"v"}, "a":[1,2,3]}`),
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Json.Get("n"), "123456789")
gtest.Assert(t.Json.Get("m"), g.Map{"k": "v"})
gtest.Assert(t.Json.Get("m.k"), "v")
gtest.Assert(t.Json.Get("a"), g.Slice{1, 2, 3})
gtest.Assert(t.Json.Get("a.1"), 2)
})
// Map
gtest.Case(t, func() {
var t *T
err := gconv.Struct(g.Map{
"name": "john",
"json": g.Map{
"n": 123456789,
"m": g.Map{"k": "v"},
"a": g.Slice{1, 2, 3},
},
}, &t)
gtest.Assert(err, nil)
gtest.Assert(t.Name, "john")
gtest.Assert(t.Json.Get("n"), "123456789")
gtest.Assert(t.Json.Get("m"), g.Map{"k": "v"})
gtest.Assert(t.Json.Get("m.k"), "v")
gtest.Assert(t.Json.Get("a"), g.Slice{1, 2, 3})
gtest.Assert(t.Json.Get("a.1"), 2)
})
}

View File

@ -7,6 +7,7 @@
package gconv
import (
"encoding/json"
"errors"
"reflect"
"strings"
@ -47,61 +48,69 @@ func doMapConvert(value interface{}, recursive bool, tags ...string) map[string]
} else {
// Assert the common combination of types, and finally it uses reflection.
m := make(map[string]interface{})
switch value.(type) {
switch r := value.(type) {
case string:
if len(r) > 0 && r[0] == '{' && r[len(r)-1] == '}' {
json.Unmarshal([]byte(r), &m)
}
case []byte:
if len(r) > 0 && r[0] == '{' && r[len(r)-1] == '}' {
json.Unmarshal(r, &m)
}
case map[interface{}]interface{}:
for k, v := range value.(map[interface{}]interface{}) {
for k, v := range r {
m[String(k)] = v
}
case map[interface{}]string:
for k, v := range value.(map[interface{}]string) {
for k, v := range r {
m[String(k)] = v
}
case map[interface{}]int:
for k, v := range value.(map[interface{}]int) {
for k, v := range r {
m[String(k)] = v
}
case map[interface{}]uint:
for k, v := range value.(map[interface{}]uint) {
for k, v := range r {
m[String(k)] = v
}
case map[interface{}]float32:
for k, v := range value.(map[interface{}]float32) {
for k, v := range r {
m[String(k)] = v
}
case map[interface{}]float64:
for k, v := range value.(map[interface{}]float64) {
for k, v := range r {
m[String(k)] = v
}
case map[string]bool:
for k, v := range value.(map[string]bool) {
for k, v := range r {
m[k] = v
}
case map[string]int:
for k, v := range value.(map[string]int) {
for k, v := range r {
m[k] = v
}
case map[string]uint:
for k, v := range value.(map[string]uint) {
for k, v := range r {
m[k] = v
}
case map[string]float32:
for k, v := range value.(map[string]float32) {
for k, v := range r {
m[k] = v
}
case map[string]float64:
for k, v := range value.(map[string]float64) {
for k, v := range r {
m[k] = v
}
case map[int]interface{}:
for k, v := range value.(map[int]interface{}) {
for k, v := range r {
m[String(k)] = v
}
case map[int]string:
for k, v := range value.(map[int]string) {
for k, v := range r {
m[String(k)] = v
}
case map[uint]string:
for k, v := range value.(map[uint]string) {
for k, v := range r {
m[String(k)] = v
}
// Not a common type, then use reflection.

View File

@ -17,6 +17,12 @@ import (
"github.com/gogf/gf/internal/utilstr"
)
// apiUnmarshalValue is the interface for custom defined types customizing value assignment.
// Note that only pointer can implement interface apiUnmarshalValue.
type apiUnmarshalValue interface {
UnmarshalValue(interface{}) error
}
var (
// replaceCharReg is the regular expression object for replacing chars
// in map keys and attribute names.
@ -42,6 +48,7 @@ func Struct(params interface{}, pointer interface{}, mapping ...map[string]strin
if pointer == nil {
return errors.New("object pointer cannot be nil")
}
// paramsMap is the map[string]interface{} type variable for params.
paramsMap := Map(params)
if paramsMap == nil {
@ -63,10 +70,19 @@ func Struct(params interface{}, pointer interface{}, mapping ...map[string]strin
}
// It automatically creates struct object if necessary.
// For example, if <pointer> is **User, then <elem> is *User, which is a pointer to User.
if elem.Type().Kind() == reflect.Ptr && (!elem.IsValid() || elem.IsNil()) {
e := reflect.New(elem.Type().Elem()).Elem()
elem.Set(e.Addr())
elem = e
if elem.Type().Kind() == reflect.Ptr {
if !elem.IsValid() || elem.IsNil() {
e := reflect.New(elem.Type().Elem()).Elem()
elem.Set(e.Addr())
elem = e
} else {
// Assign value with interface Set.
// Note that only pointer can implement interface Set.
if v, ok := elem.Interface().(apiUnmarshalValue); ok {
v.UnmarshalValue(params)
return nil
}
}
}
// It only performs one converting to the same attribute.
// doneMap is used to check repeated converting, its key is the attribute name of the struct.
@ -192,20 +208,17 @@ func StructDeep(params interface{}, pointer interface{}, mapping ...map[string]s
return nil
}
// 将参数值绑定到对象指定名称的属性上
// bindVarToStructAttr sets value to struct object attribute by name.
func bindVarToStructAttr(elem reflect.Value, name string, value interface{}) (err error) {
structFieldValue := elem.FieldByName(name)
// 键名与对象属性匹配检测map中如果有struct不存在的属性那么不做处理直接return
if !structFieldValue.IsValid() {
return nil
}
// CanSet的属性必须为公开属性(首字母大写)
// CanSet checks whether attribute is public accessible.
if !structFieldValue.CanSet() {
return nil
}
// 必须将value转换为struct属性的数据类型这里必须用到gconv包
defer func() {
// 如果转换失败,那么可能是类型不匹配造成(例如属性包含自定义类型),那么执行递归转换
if recover() != nil {
err = bindVarToReflectValue(structFieldValue, value)
}
@ -214,20 +227,17 @@ func bindVarToStructAttr(elem reflect.Value, name string, value interface{}) (er
return nil
}
// 将参数值绑定到对象指定索引位置的属性上
// bindVarToStructByIndex sets value to struct object attribute by index.
func bindVarToStructByIndex(elem reflect.Value, index int, value interface{}) (err error) {
structFieldValue := elem.FieldByIndex([]int{index})
// 键名与对象属性匹配检测
if !structFieldValue.IsValid() {
return nil
}
// CanSet的属性必须为公开属性(首字母大写)
// CanSet checks whether attribute is public accessible.
if !structFieldValue.CanSet() {
return nil
}
// 必须将value转换为struct属性的数据类型这里必须用到gconv包
defer func() {
// 如果转换失败,那么可能是类型不匹配造成(例如属性包含自定义类型),那么执行递归转换
if recover() != nil {
err = bindVarToReflectValue(structFieldValue, value)
}
@ -236,16 +246,14 @@ func bindVarToStructByIndex(elem reflect.Value, index int, value interface{}) (e
return nil
}
// 当默认的基本类型转换失败时通过recover判断后执行反射类型转换(处理复杂类型)
func bindVarToReflectValue(structFieldValue reflect.Value, value interface{}) error {
// bindVarToReflectValue sets <value> to reflect value object <structFieldValue>.
func bindVarToReflectValue(structFieldValue reflect.Value, value interface{}) (err error) {
switch structFieldValue.Kind() {
// 属性为结构体
case reflect.Struct:
if err := Struct(value, structFieldValue); err != nil {
structFieldValue.Set(reflect.ValueOf(value))
}
// 属性为数组类型
case reflect.Slice, reflect.Array:
a := reflect.Value{}
v := reflect.ValueOf(value)
@ -288,13 +296,19 @@ func bindVarToReflectValue(structFieldValue reflect.Value, value interface{}) er
}
structFieldValue.Set(a)
// 属性为指针类型
case reflect.Ptr:
e := reflect.New(structFieldValue.Type().Elem()).Elem()
if err := Struct(value, e); err != nil {
e.Set(reflect.ValueOf(value))
item := reflect.New(structFieldValue.Type().Elem())
// Assign value with interface Set.
// Note that only pointer can implement interface Set.
if v, ok := item.Interface().(apiUnmarshalValue); ok {
v.UnmarshalValue(value)
structFieldValue.Set(item)
return nil
}
elem := item.Elem()
if err = bindVarToReflectValue(elem, value); err == nil {
structFieldValue.Set(elem.Addr())
}
structFieldValue.Set(e.Addr())
case reflect.Interface:
if value == nil {
@ -304,11 +318,17 @@ func bindVarToReflectValue(structFieldValue reflect.Value, value interface{}) er
}
default:
return errors.New(
fmt.Sprintf(`cannot convert to type "%s"`,
structFieldValue.Type().String(),
),
)
defer func() {
if e := recover(); e != nil {
err = errors.New(
fmt.Sprintf(`cannot convert "%d" to type "%s"`,
value,
structFieldValue.Type().String(),
),
)
}
}()
structFieldValue.Set(reflect.ValueOf(value))
}
return nil
}