summaryrefslogtreecommitdiff
path: root/src/encoding/json/encode.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/encoding/json/encode.go')
-rw-r--r--src/encoding/json/encode.go37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go
index d8c779869b..8b967471ce 100644
--- a/src/encoding/json/encode.go
+++ b/src/encoding/json/encode.go
@@ -117,9 +117,13 @@ import (
// an anonymous struct field in both current and earlier versions, give the field
// a JSON tag of "-".
//
-// Map values encode as JSON objects. The map's key type must either be a string
-// or implement encoding.TextMarshaler. The map keys are used as JSON object
-// keys, subject to the UTF-8 coercion described for string values above.
+// Map values encode as JSON objects. The map's key type must either be a
+// string, an integer type, or implement encoding.TextMarshaler. The map keys
+// are used as JSON object keys by applying the following rules, subject to the
+// UTF-8 coercion described for string values above:
+// - string keys are used directly
+// - encoding.TextMarshalers are marshaled
+// - integer keys are converted to strings
//
// Pointer values encode as the value pointed to.
// A nil pointer encodes as the null JSON value.
@@ -644,8 +648,14 @@ func (me *mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
}
func newMapEncoder(t reflect.Type) encoderFunc {
- if t.Key().Kind() != reflect.String && !t.Key().Implements(textMarshalerType) {
- return unsupportedTypeEncoder
+ switch t.Key().Kind() {
+ case reflect.String,
+ reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+ reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ default:
+ if !t.Key().Implements(textMarshalerType) {
+ return unsupportedTypeEncoder
+ }
}
me := &mapEncoder{typeEncoder(t.Elem())}
return me.encode
@@ -806,9 +816,20 @@ func (w *reflectWithString) resolve() error {
w.s = w.v.String()
return nil
}
- buf, err := w.v.Interface().(encoding.TextMarshaler).MarshalText()
- w.s = string(buf)
- return err
+ if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok {
+ buf, err := tm.MarshalText()
+ w.s = string(buf)
+ return err
+ }
+ switch w.v.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ w.s = strconv.FormatInt(w.v.Int(), 10)
+ return nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ w.s = strconv.FormatUint(w.v.Uint(), 10)
+ return nil
+ }
+ panic("unexpected map key type")
}
// byString is a slice of reflectWithString where the reflect.Value is either