summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-02-10 18:16:16 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-10 21:49:02 -0700
commit891375baa811d92be99c950fdd377d42f03ec0d3 (patch)
tree5a65dcab81be42d93c0d7b73cff4cf211d8c1e92
parent0661700640c712d666936b15799ce8e5d5242cc7 (diff)
decode: Have .decodeArray take and return *DecodeError
-rw-r--r--decode.go40
1 files changed, 26 insertions, 14 deletions
diff --git a/decode.go b/decode.go
index 275b18c..806ee1d 100644
--- a/decode.go
+++ b/decode.go
@@ -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")
}