diff options
Diffstat (limited to 'decode.go')
-rw-r--r-- | decode.go | 40 |
1 files changed, 26 insertions, 14 deletions
@@ -663,7 +663,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { fValPtr := reflect.New(typ.Elem()) if err := dec.decode(fValPtr.Elem(), false); err != nil { - panic(decodeError(*err)) + return err } val.SetMapIndex(nameValPtr.Elem(), fValPtr.Elem()) @@ -714,17 +714,18 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { val.Set(val.Slice(0, 0)) } i := 0 - dec.decodeArray(typ, func() { + return dec.decodeArray(typ, func() *DecodeError { dec.posStackPush() defer dec.posStackPop() dec.structStackPush(typ, i) defer dec.structStackPop() mValPtr := reflect.New(typ.Elem()) if err := dec.decode(mValPtr.Elem(), false); err != nil { - panic(decodeError(*err)) + return err } val.Set(reflect.Append(val, mValPtr.Elem())) i++ + return nil }) default: dec.panicType(t.JSONType(), typ, nil) @@ -737,7 +738,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { } i := 0 n := val.Len() - dec.decodeArray(typ, func() { + if err := dec.decodeArray(typ, func() *DecodeError { dec.posStackPush() defer dec.posStackPop() dec.structStackPush(typ, i) @@ -745,14 +746,17 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) { if i < n { mValPtr := reflect.New(typ.Elem()) if err := dec.decode(mValPtr.Elem(), false); err != nil { - panic(decodeError(*err)) + return err } val.Index(i).Set(mValPtr.Elem()) } else { dec.scan(fastio.Discard) } i++ - }) + return nil + }); err != nil { + return err + } for ; i < n; i++ { val.Index(i).Set(reflect.Zero(typ.Elem())) } @@ -822,13 +826,16 @@ func (dec *Decoder) decodeAny() any { case '[': ret := []any{} typ := reflect.TypeOf(ret) - dec.decodeArray(typ, func() { + if err := dec.decodeArray(typ, func() *DecodeError { dec.posStackPush() defer dec.posStackPop() dec.structStackPush(typ, len(ret)) defer dec.structStackPop() ret = append(ret, dec.decodeAny()) - }) + return nil + }); err != nil { + panic(decodeError(*err)) + } return ret case '"': var buf strings.Builder @@ -976,7 +983,7 @@ func DecodeArray(r io.RuneScanner, decodeMember func(r io.RuneScanner) error) (e } dec.posStackPush() defer dec.posStackPop() - dec.decodeArray(nil, func() { + if err := dec.decodeArray(nil, func() *DecodeError { dec.posStackPush() defer dec.posStackPop() t := dec.peekRuneType() @@ -989,26 +996,31 @@ func DecodeArray(r io.RuneScanner, decodeMember func(r io.RuneScanner) error) (e // TODO: Find a better Go type to use than `nil`. dec.panicType(t.JSONType(), nil, fmt.Errorf("did not consume entire %s", t.JSONType())) } - }) + return nil + }); err != nil { + return err + } return nil } -func (dec *Decoder) decodeArray(gTyp reflect.Type, decodeMember func()) { +func (dec *Decoder) decodeArray(gTyp reflect.Type, decodeMember func() *DecodeError) *DecodeError { dec.expectRuneType('[', jsonparse.RuneTypeArrayBeg, gTyp) _, t := dec.readRune() switch t { case jsonparse.RuneTypeArrayEnd: - return + return nil default: dec.unreadRune() decodeNextMember: - decodeMember() + if err := decodeMember(); err != nil { + return err + } _, t := dec.readRune() switch t { case jsonparse.RuneTypeArrayComma: goto decodeNextMember case jsonparse.RuneTypeArrayEnd: - return + return nil default: panic("should not happen") } |