mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
json: preserve field name case by default
This matches the old JSON package behavior.
All lowercase names are not as standard as I believed,
and it seems less surprising to need to write
type T struct { Field string "field" }
to get lower case (behavior after this CL) than it does to need
to write
type T struct { Field string "Field" }
to preserve the case (behavior before this CL).
Also test and fix unmarshal into non-nil interface
value or pointer.
Fixes #744.
R=r
CC=golang-dev
https://golang.org/cl/1013041
This commit is contained in:
parent
cc62bed075
commit
bec40ba516
3 changed files with 164 additions and 127 deletions
|
|
@ -20,7 +20,7 @@ import (
|
|||
)
|
||||
|
||||
// Unmarshal parses the JSON-encoded data and stores the result
|
||||
// in the value pointed at by v.
|
||||
// in the value pointed to by v.
|
||||
//
|
||||
// Unmarshal traverses the value v recursively.
|
||||
// If an encountered value implements the Unmarshaler interface,
|
||||
|
|
@ -247,6 +247,10 @@ func (d *decodeState) indirect(v reflect.Value, wantptr bool) (Unmarshaler, refl
|
|||
_, isUnmarshaler = v.Interface().(Unmarshaler)
|
||||
}
|
||||
|
||||
if iv, ok := v.(*reflect.InterfaceValue); ok && !iv.IsNil() {
|
||||
v = iv.Elem()
|
||||
continue
|
||||
}
|
||||
pv, ok := v.(*reflect.PtrValue)
|
||||
if !ok {
|
||||
break
|
||||
|
|
@ -255,7 +259,9 @@ func (d *decodeState) indirect(v reflect.Value, wantptr bool) (Unmarshaler, refl
|
|||
if !isptrptr && wantptr && !isUnmarshaler {
|
||||
return nil, pv
|
||||
}
|
||||
pv.PointTo(reflect.MakeZero(pv.Type().(*reflect.PtrType).Elem()))
|
||||
if pv.IsNil() {
|
||||
pv.PointTo(reflect.MakeZero(pv.Type().(*reflect.PtrType).Elem()))
|
||||
}
|
||||
if isUnmarshaler {
|
||||
// Using v.Interface().(Unmarshaler)
|
||||
// here means that we have to use a pointer
|
||||
|
|
@ -436,11 +442,12 @@ func (d *decodeState) object(v reflect.Value) {
|
|||
d.error(errPhase)
|
||||
}
|
||||
|
||||
// Figure out
|
||||
// Figure out field corresponding to key.
|
||||
var subv reflect.Value
|
||||
if mv != nil {
|
||||
subv = reflect.MakeZero(mv.Type().(*reflect.MapType).Elem())
|
||||
} else {
|
||||
// First try for field with that tag.
|
||||
for i := 0; i < sv.NumField(); i++ {
|
||||
f := sv.Type().(*reflect.StructType).Field(i)
|
||||
if f.Tag == key {
|
||||
|
|
@ -449,7 +456,12 @@ func (d *decodeState) object(v reflect.Value) {
|
|||
}
|
||||
}
|
||||
if subv == nil {
|
||||
subv = sv.FieldByNameFunc(func(s string) bool { return matchName(key, s) })
|
||||
// Second, exact match.
|
||||
subv = sv.FieldByName(key)
|
||||
if subv == nil {
|
||||
// Third, case-insensitive match.
|
||||
subv = sv.FieldByNameFunc(func(s string) bool { return matchName(key, s) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue