Tao Wen 8 anni fa
parent
commit
10a1fb8762
3 ha cambiato i file con 67 aggiunte e 3 eliminazioni
  1. 12 1
      feature_any.go
  2. 36 2
      feature_any_object.go
  3. 19 0
      jsoniter_map_test.go

+ 12 - 1
feature_any.go

@@ -80,12 +80,17 @@ func WrapString(val string) Any {
 }
 
 func Wrap(val interface{}) Any {
+	if val == nil {
+		return &nilAny{}
+	}
 	type_ := reflect.TypeOf(val)
 	switch type_.Kind() {
 	case reflect.Slice:
 		return wrapArray(val)
 	case reflect.Struct:
 		return wrapStruct(val)
+	case reflect.Map:
+		return wrapMap(val)
 	case reflect.String:
 		return WrapString(val.(string))
 	case reflect.Int:
@@ -112,8 +117,14 @@ func Wrap(val interface{}) Any {
 		return WrapFloat64(float64(val.(float32)))
 	case reflect.Float64:
 		return WrapFloat64(val.(float64))
+	case reflect.Bool:
+		if val.(bool) == true {
+			return &trueAny{}
+		} else {
+			return &falseAny{}
+		}
 	}
-	return nil
+	return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", type_)}
 }
 
 func (iter *Iterator) ReadAny() Any {

+ 36 - 2
feature_any_object.go

@@ -360,6 +360,9 @@ func (any *objectAny) fillCache() {
 	if any.cache == nil {
 		any.cache = map[string]Any{}
 	}
+	if len(any.cache) == any.val.NumField() {
+		return
+	}
 	for i := 0; i < any.val.NumField(); i++ {
 		field := any.val.Field(i)
 		fieldName := any.val.Type().Field(i).Name
@@ -549,7 +552,6 @@ func (any *objectAny) GetInterface() interface{} {
 	return any.cache
 }
 
-
 type mapAny struct {
 	baseAny
 	err   error
@@ -593,6 +595,17 @@ func (any *mapAny) fillCacheUntil(target string) Any {
 }
 
 func (any *mapAny) fillCache() {
+	if any.cache == nil {
+		any.cache = map[string]Any{}
+	}
+	if len(any.cache) == len(any.val.MapKeys()) {
+		return
+	}
+	for _, key := range any.val.MapKeys() {
+		keyAsStr := key.String()
+		element := Wrap(any.val.MapIndex(key).Interface())
+		any.cache[keyAsStr] = element
+	}
 }
 
 func (any *mapAny) LastError() error {
@@ -705,7 +718,28 @@ func (any *mapAny) Size() int {
 }
 
 func (any *mapAny) IterateObject() (func() (string, Any, bool), bool) {
-	return nil, false
+	any.fillCache()
+	if len(any.cache) == 0 {
+		return nil, false
+	}
+	keys := make([]string, len(any.cache))
+	values := make([]Any, len(any.cache))
+	i := 0
+	for k, v := range any.cache {
+		keys[i] = k
+		values[i] = v
+		i++
+	}
+	i = 0
+	return func() (string, Any, bool) {
+		if i == len(keys) {
+			return "", nil, false
+		}
+		k := keys[i]
+		v := values[i]
+		i++
+		return k, v, i != len(keys)
+	}, true
 }
 
 func (any *mapAny) GetObject() map[string]Any {

+ 19 - 0
jsoniter_map_test.go

@@ -24,6 +24,25 @@ func Test_read_map_of_interface(t *testing.T) {
 	should.Equal(map[string]interface{}{"hello": "world"}, iter.Read())
 }
 
+func Test_wrap_map(t *testing.T) {
+	should := require.New(t)
+	any := Wrap(map[string]string{"Field1": "hello"})
+	should.Equal("hello", any.Get("Field1").ToString())
+	any = Wrap(map[string]string{"Field1": "hello"})
+	should.Equal(1, any.Size())
+	any = Wrap(map[string]string{"Field1": "hello"})
+	vals := map[string]string{}
+	var k string
+	var v Any
+	for next, hasNext := any.IterateObject(); hasNext; {
+		k, v, hasNext = next()
+		if v.ValueType() == String {
+			vals[k] = v.ToString()
+		}
+	}
+	should.Equal(map[string]string{"Field1":"hello"}, vals)
+}
+
 func Test_write_val_map(t *testing.T) {
 	should := require.New(t)
 	val := map[string]string{"1": "2"}