add UnmarshalJSON func tion for gmap/gvar

This commit is contained in:
John 2019-09-30 14:23:15 +08:00
parent 8eb1b685a5
commit ee1414c010
23 changed files with 676 additions and 36 deletions

View File

@ -9,6 +9,7 @@ package garray
import (
"bytes"
"encoding/json"
"github.com/gogf/gf/util/gutil"
"math"
"sort"
@ -85,6 +86,10 @@ func (a *SortedArray) SetComparator(comparator func(a, b interface{}) int) {
a.mu.Lock()
defer a.mu.Unlock()
a.comparator = comparator
// Resort the array if comparator is changed.
sort.Slice(a.array, func(i, j int) bool {
return a.comparator(a.array[i], a.array[j]) < 0
})
}
// Sort sorts the array in increasing order.
@ -564,8 +569,8 @@ func (a *SortedArray) UnmarshalJSON(b []byte) error {
a.mu = rwmutex.New()
a.array = make([]interface{}, 0)
a.unique = gtype.NewBool()
// Note that the comparator is nil in default.
a.comparator = nil
// Note that the comparator is string comparator in default.
a.comparator = gutil.ComparatorString
}
a.mu.Lock()
defer a.mu.Unlock()

View File

@ -377,3 +377,19 @@ func (l *List) IteratorDesc(f func(e *Element) bool) {
func (l *List) MarshalJSON() ([]byte, error) {
return json.Marshal(l.FrontAll())
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (l *List) UnmarshalJSON(b []byte) error {
if l.mu == nil {
l.mu = rwmutex.New()
l.list = list.New()
}
l.mu.Lock()
defer l.mu.Unlock()
var array []interface{}
if err := json.Unmarshal(b, &array); err != nil {
return err
}
l.PushBacks(array)
return nil
}

View File

@ -8,6 +8,7 @@ package glist
import (
"container/list"
"encoding/json"
"github.com/gogf/gf/test/gtest"
"github.com/gogf/gf/util/gconv"
@ -583,3 +584,37 @@ func TestList_Iterator(t *testing.T) {
l.Iterator(fun1)
checkList(t, l, []interface{}{"e", "d", "c", "b", "a"})
}
func TestList_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
a := []interface{}{"a", "b", "c"}
l := New()
l.PushBacks(a)
b1, err1 := json.Marshal(l)
b2, err2 := json.Marshal(a)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
a := []interface{}{"a", "b", "c"}
l := New()
b, err := json.Marshal(a)
gtest.Assert(err, nil)
err = json.Unmarshal(b, l)
gtest.Assert(err, nil)
gtest.Assert(l.FrontAll(), a)
})
gtest.Case(t, func() {
var l List
a := []interface{}{"a", "b", "c"}
b, err := json.Marshal(a)
gtest.Assert(err, nil)
err = json.Unmarshal(b, &l)
gtest.Assert(err, nil)
gtest.Assert(l.FrontAll(), a)
})
}

View File

@ -377,3 +377,21 @@ func (m *AnyAnyMap) Merge(other *AnyAnyMap) {
func (m *AnyAnyMap) MarshalJSON() ([]byte, error) {
return json.Marshal(gconv.Map(m.Map()))
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (m *AnyAnyMap) UnmarshalJSON(b []byte) error {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[interface{}]interface{})
}
m.mu.Lock()
defer m.mu.Unlock()
var data map[string]interface{}
if err := json.Unmarshal(b, &data); err != nil {
return err
}
for k, v := range data {
m.data[k] = v
}
return nil
}

View File

@ -368,3 +368,17 @@ func (m *IntAnyMap) MarshalJSON() ([]byte, error) {
defer m.mu.RUnlock()
return json.Marshal(m.data)
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (m *IntAnyMap) UnmarshalJSON(b []byte) error {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[int]interface{})
}
m.mu.Lock()
defer m.mu.Unlock()
if err := json.Unmarshal(b, &m.data); err != nil {
return err
}
return nil
}

View File

@ -344,3 +344,17 @@ func (m *IntIntMap) MarshalJSON() ([]byte, error) {
defer m.mu.RUnlock()
return json.Marshal(m.data)
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (m *IntIntMap) UnmarshalJSON(b []byte) error {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[int]int)
}
m.mu.Lock()
defer m.mu.Unlock()
if err := json.Unmarshal(b, &m.data); err != nil {
return err
}
return nil
}

View File

@ -345,3 +345,17 @@ func (m *IntStrMap) MarshalJSON() ([]byte, error) {
defer m.mu.RUnlock()
return json.Marshal(m.data)
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (m *IntStrMap) UnmarshalJSON(b []byte) error {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[int]string)
}
m.mu.Lock()
defer m.mu.Unlock()
if err := json.Unmarshal(b, &m.data); err != nil {
return err
}
return nil
}

View File

@ -370,3 +370,17 @@ func (m *StrAnyMap) MarshalJSON() ([]byte, error) {
defer m.mu.RUnlock()
return json.Marshal(m.data)
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (m *StrAnyMap) UnmarshalJSON(b []byte) error {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[string]interface{})
}
m.mu.Lock()
defer m.mu.Unlock()
if err := json.Unmarshal(b, &m.data); err != nil {
return err
}
return nil
}

View File

@ -347,3 +347,17 @@ func (m *StrIntMap) MarshalJSON() ([]byte, error) {
defer m.mu.RUnlock()
return json.Marshal(m.data)
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (m *StrIntMap) UnmarshalJSON(b []byte) error {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[string]int)
}
m.mu.Lock()
defer m.mu.Unlock()
if err := json.Unmarshal(b, &m.data); err != nil {
return err
}
return nil
}

View File

@ -347,3 +347,17 @@ func (m *StrStrMap) MarshalJSON() ([]byte, error) {
defer m.mu.RUnlock()
return json.Marshal(m.data)
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (m *StrStrMap) UnmarshalJSON(b []byte) error {
if m.mu == nil {
m.mu = rwmutex.New()
m.data = make(map[string]string)
}
m.mu.Lock()
defer m.mu.Unlock()
if err := json.Unmarshal(b, &m.data); err != nil {
return err
}
return nil
}

View File

@ -412,3 +412,26 @@ func (m *ListMap) Merge(other *ListMap) {
func (m *ListMap) MarshalJSON() ([]byte, error) {
return json.Marshal(gconv.Map(m.Map()))
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (m *ListMap) UnmarshalJSON(b []byte) 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()
var data map[string]interface{}
if err := json.Unmarshal(b, &data); err != nil {
return err
}
for key, value := range data {
if e, ok := m.data[key]; !ok {
m.data[key] = m.list.PushBack(&gListMapNode{key, value})
} else {
e.Value = &gListMapNode{key, value}
}
}
return nil
}

View File

@ -7,6 +7,9 @@
package gmap_test
import (
"encoding/json"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/util/gconv"
"testing"
"github.com/gogf/gf/container/gmap"
@ -174,3 +177,47 @@ func Test_AnyAnyMap_FilterEmpty(t *testing.T) {
gtest.Assert(m.Get(1), nil)
gtest.Assert(m.Get(2), 2)
}
func Test_AnyAnyMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
m1 := gmap.NewAnyAnyMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(gconv.Map(data))
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(gconv.Map(data))
gtest.Assert(err, nil)
m := gmap.New()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
})
gtest.Case(t, func() {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(gconv.Map(data))
gtest.Assert(err, nil)
var m gmap.Map
err = json.Unmarshal(b, &m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
})
}

View File

@ -7,6 +7,8 @@
package gmap_test
import (
"encoding/json"
"github.com/gogf/gf/frame/g"
"testing"
"github.com/gogf/gf/container/gmap"
@ -171,3 +173,33 @@ func Test_IntAnyMap_FilterEmpty(t *testing.T) {
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get(2), 2)
}
func Test_IntAnyMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
data := g.MapIntAny{
1: "v1",
2: "v2",
}
m1 := gmap.NewIntAnyMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(data)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
data := g.MapIntAny{
1: "v1",
2: "v2",
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
m := gmap.NewIntAnyMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get(1), data[1])
gtest.Assert(m.Get(2), data[2])
})
}

View File

@ -7,6 +7,8 @@
package gmap_test
import (
"encoding/json"
"github.com/gogf/gf/frame/g"
"testing"
"github.com/gogf/gf/container/gmap"
@ -174,3 +176,33 @@ func Test_IntIntMap_FilterEmpty(t *testing.T) {
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get(2), 2)
}
func Test_IntIntMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
data := g.MapIntInt{
1: 10,
2: 20,
}
m1 := gmap.NewIntIntMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(data)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
data := g.MapIntInt{
1: 10,
2: 20,
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
m := gmap.NewIntIntMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get(1), data[1])
gtest.Assert(m.Get(2), data[2])
})
}

View File

@ -7,6 +7,8 @@
package gmap_test
import (
"encoding/json"
"github.com/gogf/gf/frame/g"
"testing"
"github.com/gogf/gf/container/gmap"
@ -175,3 +177,33 @@ func Test_IntStrMap_FilterEmpty(t *testing.T) {
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get(2), "2")
}
func Test_IntStrMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
data := g.MapIntStr{
1: "v1",
2: "v2",
}
m1 := gmap.NewIntStrMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(data)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
data := g.MapIntStr{
1: "v1",
2: "v2",
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
m := gmap.NewIntStrMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get(1), data[1])
gtest.Assert(m.Get(2), data[2])
})
}

View File

@ -7,6 +7,8 @@
package gmap_test
import (
"encoding/json"
"github.com/gogf/gf/util/gconv"
"testing"
"github.com/gogf/gf/container/gmap"
@ -14,7 +16,7 @@ import (
"github.com/gogf/gf/test/gtest"
)
func Test_List_Map_Basic(t *testing.T) {
func Test_ListMap_Basic(t *testing.T) {
gtest.Case(t, func() {
m := gmap.NewListMap()
m.Set("key1", "val1")
@ -48,7 +50,7 @@ func Test_List_Map_Basic(t *testing.T) {
gtest.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
})
}
func Test_List_Map_Set_Fun(t *testing.T) {
func Test_ListMap_Set_Fun(t *testing.T) {
m := gmap.NewListMap()
m.GetOrSetFunc("fun", getValue)
m.GetOrSetFuncLock("funlock", getValue)
@ -59,14 +61,14 @@ func Test_List_Map_Set_Fun(t *testing.T) {
gtest.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
}
func Test_List_Map_Batch(t *testing.T) {
func Test_ListMap_Batch(t *testing.T) {
m := gmap.NewListMap()
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
gtest.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
gtest.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
}
func Test_List_Map_Iterator(t *testing.T) {
func Test_ListMap_Iterator(t *testing.T) {
expect := map[interface{}]interface{}{1: 1, "key1": "val1"}
m := gmap.NewListMapFrom(expect)
@ -89,7 +91,7 @@ func Test_List_Map_Iterator(t *testing.T) {
gtest.Assert(j, 1)
}
func Test_List_Map_Clone(t *testing.T) {
func Test_ListMap_Clone(t *testing.T) {
//clone 方法是深克隆
m := gmap.NewListMapFrom(map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
@ -102,7 +104,7 @@ func Test_List_Map_Clone(t *testing.T) {
gtest.AssertIN("key1", m.Keys())
}
func Test_List_Map_Basic_Merge(t *testing.T) {
func Test_ListMap_Basic_Merge(t *testing.T) {
m1 := gmap.NewListMap()
m2 := gmap.NewListMap()
m1.Set("key1", "val1")
@ -111,7 +113,7 @@ func Test_List_Map_Basic_Merge(t *testing.T) {
gtest.Assert(m1.Map(), map[interface{}]interface{}{"key1": "val1", "key2": "val2"})
}
func Test_List_Map_Order(t *testing.T) {
func Test_ListMap_Order(t *testing.T) {
m := gmap.NewListMap()
m.Set("k1", "v1")
m.Set("k2", "v2")
@ -130,3 +132,48 @@ func Test_ListMap_FilterEmpty(t *testing.T) {
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get(2), "2")
}
func Test_ListMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
m1 := gmap.NewListMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(gconv.Map(data))
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(gconv.Map(data))
gtest.Assert(err, nil)
m := gmap.NewListMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
})
gtest.Case(t, func() {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(gconv.Map(data))
gtest.Assert(err, nil)
var m gmap.ListMap
err = json.Unmarshal(b, &m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
})
}

View File

@ -7,6 +7,8 @@
package gmap_test
import (
"encoding/json"
"github.com/gogf/gf/frame/g"
"testing"
"github.com/gogf/gf/container/gmap"
@ -169,3 +171,47 @@ func Test_StrAnyMap_FilterEmpty(t *testing.T) {
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get("2"), 2)
}
func Test_StrAnyMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
data := g.MapStrAny{
"k1": "v1",
"k2": "v2",
}
m1 := gmap.NewStrAnyMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(data)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
data := g.MapStrAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
m := gmap.NewStrAnyMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
})
gtest.Case(t, func() {
data := g.MapStrAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
var m gmap.StrAnyMap
err = json.Unmarshal(b, &m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
})
}

View File

@ -7,6 +7,8 @@
package gmap_test
import (
"encoding/json"
"github.com/gogf/gf/frame/g"
"testing"
"github.com/gogf/gf/container/gmap"
@ -172,3 +174,47 @@ func Test_StrIntMap_FilterEmpty(t *testing.T) {
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get("2"), 2)
}
func Test_StrIntMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
data := g.MapStrInt{
"k1": 1,
"k2": 2,
}
m1 := gmap.NewStrIntMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(data)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
data := g.MapStrInt{
"k1": 1,
"k2": 2,
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
m := gmap.NewStrIntMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
})
gtest.Case(t, func() {
data := g.MapStrInt{
"k1": 1,
"k2": 2,
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
var m gmap.StrIntMap
err = json.Unmarshal(b, &m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
})
}

View File

@ -7,6 +7,8 @@
package gmap_test
import (
"encoding/json"
"github.com/gogf/gf/frame/g"
"testing"
"github.com/gogf/gf/container/gmap"
@ -169,3 +171,47 @@ func Test_StrStrMap_FilterEmpty(t *testing.T) {
gtest.Assert(m.Size(), 1)
gtest.Assert(m.Get("2"), "2")
}
func Test_StrStrMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
data := g.MapStrStr{
"k1": "v1",
"k2": "v2",
}
m1 := gmap.NewStrStrMapFrom(data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(data)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
data := g.MapStrStr{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
m := gmap.NewStrStrMap()
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
})
gtest.Case(t, func() {
data := g.MapStrStr{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(data)
gtest.Assert(err, nil)
var m gmap.StrStrMap
err = json.Unmarshal(b, &m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
})
}

View File

@ -7,6 +7,9 @@
package gmap_test
import (
"encoding/json"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/util/gconv"
"testing"
"github.com/gogf/gf/container/gmap"
@ -14,7 +17,7 @@ import (
"github.com/gogf/gf/util/gutil"
)
func Test_Tree_Map_Basic(t *testing.T) {
func Test_TreeMap_Basic(t *testing.T) {
gtest.Case(t, func() {
m := gmap.NewTreeMap(gutil.ComparatorString)
m.Set("key1", "val1")
@ -48,7 +51,7 @@ func Test_Tree_Map_Basic(t *testing.T) {
gtest.Assert(m2.Map(), map[interface{}]interface{}{1: 1, "key1": "val1"})
})
}
func Test_Tree_Map_Set_Fun(t *testing.T) {
func Test_TreeMap_Set_Fun(t *testing.T) {
m := gmap.NewTreeMap(gutil.ComparatorString)
m.GetOrSetFunc("fun", getValue)
m.GetOrSetFuncLock("funlock", getValue)
@ -59,14 +62,14 @@ func Test_Tree_Map_Set_Fun(t *testing.T) {
gtest.Assert(m.SetIfNotExistFuncLock("funlock", getValue), false)
}
func Test_Tree_Map_Batch(t *testing.T) {
func Test_TreeMap_Batch(t *testing.T) {
m := gmap.NewTreeMap(gutil.ComparatorString)
m.Sets(map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
gtest.Assert(m.Map(), map[interface{}]interface{}{1: 1, "key1": "val1", "key2": "val2", "key3": "val3"})
m.Removes([]interface{}{"key1", 1})
gtest.Assert(m.Map(), map[interface{}]interface{}{"key2": "val2", "key3": "val3"})
}
func Test_Tree_Map_Iterator(t *testing.T) {
func Test_TreeMap_Iterator(t *testing.T) {
expect := map[interface{}]interface{}{1: 1, "key1": "val1"}
m := gmap.NewTreeMapFrom(gutil.ComparatorString, expect)
@ -89,7 +92,7 @@ func Test_Tree_Map_Iterator(t *testing.T) {
gtest.Assert(j, 1)
}
func Test_Tree_Map_Clone(t *testing.T) {
func Test_TreeMap_Clone(t *testing.T) {
//clone 方法是深克隆
m := gmap.NewTreeMapFrom(gutil.ComparatorString, map[interface{}]interface{}{1: 1, "key1": "val1"})
m_clone := m.Clone()
@ -101,3 +104,47 @@ func Test_Tree_Map_Clone(t *testing.T) {
//修改clone map,原 map 不影响
gtest.AssertIN("key1", m.Keys())
}
func Test_TreeMap_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
m1 := gmap.NewTreeMapFrom(gutil.ComparatorString, data)
b1, err1 := json.Marshal(m1)
b2, err2 := json.Marshal(gconv.Map(data))
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(gconv.Map(data))
gtest.Assert(err, nil)
m := gmap.NewTreeMap(gutil.ComparatorString)
err = json.Unmarshal(b, m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
})
gtest.Case(t, func() {
data := g.MapAnyAny{
"k1": "v1",
"k2": "v2",
}
b, err := json.Marshal(gconv.Map(data))
gtest.Assert(err, nil)
var m gmap.TreeMap
err = json.Unmarshal(b, &m)
gtest.Assert(err, nil)
gtest.Assert(m.Get("k1"), data["k1"])
gtest.Assert(m.Get("k2"), data["k2"])
})
}

View File

@ -9,8 +9,8 @@ package gtree
import (
"encoding/json"
"fmt"
"github.com/gogf/gf/util/gconv"
"github.com/gogf/gf/util/gutil"
"github.com/gogf/gf/container/gvar"
"github.com/gogf/gf/internal/rwmutex"
@ -61,6 +61,26 @@ func NewRedBlackTreeFrom(comparator func(v1, v2 interface{}) int, data map[inter
return tree
}
// SetComparator sets/changes the comparator for sorting.
func (tree *RedBlackTree) SetComparator(comparator func(a, b interface{}) int) {
tree.mu.Lock()
defer tree.mu.Unlock()
tree.comparator = comparator
if tree.size > 0 {
data := make(map[interface{}]interface{}, tree.size)
tree.doIteratorAsc(tree.leftNode(), func(key, value interface{}) bool {
data[key] = value
return true
})
// Resort the tree if comparator is changed.
tree.root = nil
tree.size = 0
for k, v := range data {
tree.doSet(k, v)
}
}
}
// Clone returns a new tree with a copy of current tree.
func (tree *RedBlackTree) Clone(safe ...bool) *RedBlackTree {
newTree := NewRedBlackTree(tree.comparator, !tree.mu.IsSafe())
@ -889,5 +909,23 @@ func (tree *RedBlackTree) nodeColor(node *RedBlackTreeNode) color {
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
func (tree *RedBlackTree) MarshalJSON() ([]byte, error) {
return json.Marshal(tree.Map())
return json.Marshal(gconv.Map(tree.Map()))
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (tree *RedBlackTree) UnmarshalJSON(b []byte) error {
if tree.mu == nil {
tree.mu = rwmutex.New()
tree.comparator = gutil.ComparatorString
}
tree.mu.Lock()
defer tree.mu.Unlock()
var data map[string]interface{}
if err := json.Unmarshal(b, &data); err != nil {
return err
}
for k, v := range data {
tree.doSet(k, v)
}
return nil
}

View File

@ -38,22 +38,6 @@ func New(value interface{}, safe ...bool) *Var {
return v
}
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
func (v *Var) MarshalJSON() ([]byte, error) {
return json.Marshal(v.Val())
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (v *Var) UnmarshalJSON(b []byte) error {
var i interface{}
err := json.Unmarshal(b, &i)
if err != nil {
return err
}
v.Set(i)
return nil
}
// Set sets <value> to <v>, and returns the old value.
func (v *Var) Set(value interface{}) (old interface{}) {
if v.safe {
@ -338,3 +322,19 @@ func (v *Var) MapToMaps(pointer interface{}, mapping ...map[string]string) (err
func (v *Var) MapToMapsDeep(pointer interface{}, mapping ...map[string]string) (err error) {
return gconv.MapToMapsDeep(v.Val(), pointer, mapping...)
}
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
func (v *Var) MarshalJSON() ([]byte, error) {
return json.Marshal(v.Val())
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (v *Var) UnmarshalJSON(b []byte) error {
var i interface{}
err := json.Unmarshal(b, &i)
if err != nil {
return err
}
v.Set(i)
return nil
}

View File

@ -9,6 +9,8 @@ package gvar_test
import (
"bytes"
"encoding/binary"
"encoding/json"
"math"
"testing"
"time"
@ -300,12 +302,12 @@ func Test_Map(t *testing.T) {
})
}
type StTest struct {
Test int
}
func Test_Struct(t *testing.T) {
gtest.Case(t, func() {
type StTest struct {
Test int
}
Kv := make(map[string]int, 1)
Kv["Test"] = 100
@ -318,3 +320,47 @@ func Test_Struct(t *testing.T) {
gtest.Assert(testObj.Test, Kv["Test"])
})
}
func Test_Json(t *testing.T) {
// Marshal
gtest.Case(t, func() {
s := "i love gf"
v := gvar.New(s)
b1, err1 := json.Marshal(v)
b2, err2 := json.Marshal(s)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
})
gtest.Case(t, func() {
s := math.MaxInt64
v := gvar.New(s)
b1, err1 := json.Marshal(v)
b2, err2 := json.Marshal(s)
gtest.Assert(err1, err2)
gtest.Assert(b1, b2)
})
// Unmarshal
gtest.Case(t, func() {
s := "i love gf"
v := gvar.New(nil)
b, err := json.Marshal(s)
gtest.Assert(err, nil)
err = json.Unmarshal(b, v)
gtest.Assert(err, nil)
gtest.Assert(v.String(), s)
})
gtest.Case(t, func() {
var v gvar.Var
s := "i love gf"
b, err := json.Marshal(s)
gtest.Assert(err, nil)
err = json.Unmarshal(b, &v)
gtest.Assert(err, nil)
gtest.Assert(v.String(), s)
})
}