]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/json: encode map key is of string kind, decode only of string type
authorRyan Slade <ryanslade@gmail.com>
Sun, 30 Dec 2012 04:40:42 +0000 (15:40 +1100)
committerDave Cheney <dave@cheney.net>
Sun, 30 Dec 2012 04:40:42 +0000 (15:40 +1100)
Allows encoding and decoding of maps with key of string kind, not just string type.
Fixes #3519.

R=rsc, dave
CC=golang-dev
https://golang.org/cl/6943047

src/pkg/encoding/json/decode.go
src/pkg/encoding/json/decode_test.go

index b46dac96f5df8ef2821ec22a5f7c225d241640e2..93a8eb8e9290b5f70ce9a5b9b67b75eec1f9e584 100644 (file)
@@ -430,9 +430,9 @@ func (d *decodeState) object(v reflect.Value) {
        // Check type of target: struct or map[string]T
        switch v.Kind() {
        case reflect.Map:
-               // map must have string type
+               // map must have string kind
                t := v.Type()
-               if t.Key() != reflect.TypeOf("") {
+               if t.Key().Kind() != reflect.String {
                        d.saveError(&UnmarshalTypeError{"object", v.Type()})
                        break
                }
@@ -536,10 +536,12 @@ func (d *decodeState) object(v reflect.Value) {
                } else {
                        d.value(subv)
                }
+
                // Write value back to map;
                // if using struct, subv points into struct already.
                if v.Kind() == reflect.Map {
-                       v.SetMapIndex(reflect.ValueOf(key), subv)
+                       kv := reflect.ValueOf(key).Convert(v.Type().Key())
+                       v.SetMapIndex(kv, subv)
                }
 
                // Next token must be , or }.
index b9fad0597a6d0d17727f240826d57d005b186951..4f334d1347d741efcfb3d130c04c17ee5b3f2c0c 100644 (file)
@@ -1000,3 +1000,28 @@ func TestUnmarshalNulls(t *testing.T) {
                t.Errorf("Unmarshal of null values affected primitives")
        }
 }
+
+func TestStringKind(t *testing.T) {
+       type stringKind string
+       type aMap map[stringKind]int
+
+       var m1, m2 map[stringKind]int
+       m1 = map[stringKind]int{
+               "foo": 42,
+       }
+
+       data, err := Marshal(m1)
+       if err != nil {
+               t.Errorf("Unexpected error marshalling: %v", err)
+       }
+
+       err = Unmarshal(data, &m2)
+       if err != nil {
+               t.Errorf("Unexpected error unmarshalling: %v", err)
+       }
+
+       if !reflect.DeepEqual(m1, m2) {
+               t.Error("Items should be equal after encoding and then decoding")
+       }
+
+}