mirror of https://github.com/golang/go.git
json: allow one to unmarshal a top-level JSON array.
Fixies issue 114. R=rsc CC=golang-dev https://golang.org/cl/154121
This commit is contained in:
parent
e7b8f5faca
commit
bccc337084
|
|
@ -224,7 +224,7 @@ func (b *structBuilder) Key(k string) Builder {
|
|||
}
|
||||
|
||||
// Unmarshal parses the JSON syntax string s and fills in
|
||||
// an arbitrary struct or array pointed at by val.
|
||||
// an arbitrary struct or slice pointed at by val.
|
||||
// It uses the reflect package to assign to fields
|
||||
// and arrays embedded in val. Well-formed data that does not fit
|
||||
// into the struct is discarded.
|
||||
|
|
@ -279,11 +279,27 @@ func (b *structBuilder) Key(k string) Builder {
|
|||
// assign to upper case fields. Unmarshal uses a case-insensitive
|
||||
// comparison to match JSON field names to struct field names.
|
||||
//
|
||||
// To unmarshal a top-level JSON array, pass in a pointer to an empty
|
||||
// slice of the correct type.
|
||||
//
|
||||
// On success, Unmarshal returns with ok set to true.
|
||||
// On a syntax error, it returns with ok set to false and errtok
|
||||
// set to the offending token.
|
||||
func Unmarshal(s string, val interface{}) (ok bool, errtok string) {
|
||||
b := &structBuilder{val: reflect.NewValue(val)};
|
||||
v := reflect.NewValue(val);
|
||||
var b *structBuilder;
|
||||
|
||||
// If val is a pointer to a slice, we mutate the pointee.
|
||||
if ptr, ok := v.(*reflect.PtrValue); ok {
|
||||
if slice, ok := ptr.Elem().(*reflect.SliceValue); ok {
|
||||
b = &structBuilder{val: slice}
|
||||
}
|
||||
}
|
||||
|
||||
if b == nil {
|
||||
b = &structBuilder{val: v}
|
||||
}
|
||||
|
||||
ok, _, errtok = Parse(s, b);
|
||||
if !ok {
|
||||
return false, errtok
|
||||
|
|
|
|||
|
|
@ -126,9 +126,34 @@ func TestIssue147(t *testing.T) {
|
|||
var timeline Issue147;
|
||||
Unmarshal(issue147Input, &timeline);
|
||||
|
||||
if len(timeline.Test) != 30 {
|
||||
t.Errorf("wrong length: got %d want 30", len(timeline.Test))
|
||||
}
|
||||
|
||||
for i, e := range timeline.Test {
|
||||
if e.Text != strconv.Itoa(i) {
|
||||
t.Errorf("index: %d got: %s want: %d", i, e.Text, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Issue114 struct {
|
||||
Text string;
|
||||
}
|
||||
|
||||
const issue114Input = `[{"text" : "0"}, {"text" : "1"}, {"text" : "2"}, {"text" : "3"}]`
|
||||
|
||||
func TestIssue114(t *testing.T) {
|
||||
var items []Issue114;
|
||||
Unmarshal(issue114Input, &items);
|
||||
|
||||
if len(items) != 4 {
|
||||
t.Errorf("wrong length: got %d want 4", len(items))
|
||||
}
|
||||
|
||||
for i, e := range items {
|
||||
if e.Text != strconv.Itoa(i) {
|
||||
t.Errorf("index: %d got: %s want: %d", i, e.Text, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue