summaryrefslogtreecommitdiff
path: root/decode.go
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-02-10 18:09:19 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-10 21:49:02 -0700
commit0661700640c712d666936b15799ce8e5d5242cc7 (patch)
tree6abeea713748cb9c9fab66bdd25b415f344753b6 /decode.go
parentef47f7b3b0c39c6512f55a48324342f95063d3a3 (diff)
decode: Have .decodeObject take and return *DecodeError
Diffstat (limited to 'decode.go')
-rw-r--r--decode.go54
1 files changed, 34 insertions, 20 deletions
diff --git a/decode.go b/decode.go
index 976ab9b..275b18c 100644
--- a/decode.go
+++ b/decode.go
@@ -530,12 +530,13 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
}
index := jsonstruct.IndexStruct(typ)
var nameBuf strings.Builder
- dec.decodeObject(typ, func() {
+ return dec.decodeObject(typ, func() *DecodeError {
dec.posStackPush()
defer dec.posStackPop()
nameBuf.Reset()
dec.decodeString(nil, &nameBuf)
- }, func() {
+ return nil
+ }, func() *DecodeError {
dec.posStackPush()
defer dec.posStackPop()
name := nameBuf.String()
@@ -556,7 +557,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
dec.panicType("", typ, fmt.Errorf("json: unknown field %q", name))
}
dec.scan(fastio.Discard)
- return
+ return nil
}
field := index.ByPos[idx]
fVal := val
@@ -604,10 +605,9 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v",
fVal.Type()))
}
+ return nil
} else {
- if err := dec.decode(fVal, true); err != nil {
- panic(decodeError(*err))
- }
+ return dec.decode(fVal, true)
}
})
case reflect.Map:
@@ -621,7 +621,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
}
var nameBuf bytes.Buffer
var nameValPtr reflect.Value
- dec.decodeObject(typ, func() {
+ return dec.decodeObject(typ, func() *DecodeError {
dec.posStackPush()
defer dec.posStackPop()
nameBuf.Reset()
@@ -654,7 +654,8 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
dec.panicType("object", typ, &DecodeArgumentError{Type: nameValTyp})
}
}
- }, func() {
+ return nil
+ }, func() *DecodeError {
dec.posStackPush()
defer dec.posStackPop()
dec.structStackPush(typ, nameValPtr.Elem())
@@ -666,6 +667,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
}
val.SetMapIndex(nameValPtr.Elem(), fValPtr.Elem())
+ return nil
})
default:
dec.panicType(t.JSONType(), typ, nil)
@@ -799,19 +801,23 @@ func (dec *Decoder) decodeAny() any {
ret := make(map[string]any)
typ := reflect.TypeOf(ret)
var nameBuf strings.Builder
- dec.decodeObject(typ, func() {
+ if err := dec.decodeObject(typ, func() *DecodeError {
dec.posStackPush()
defer dec.posStackPop()
nameBuf.Reset()
dec.decodeString(nil, &nameBuf)
- }, func() {
+ return nil
+ }, func() *DecodeError {
dec.posStackPush()
defer dec.posStackPop()
name := nameBuf.String()
dec.structStackPush(typ, name)
defer dec.structStackPop()
ret[name] = dec.decodeAny()
- })
+ return nil
+ }); err != nil {
+ panic(decodeError(*err))
+ }
return ret
case '[':
ret := []any{}
@@ -877,8 +883,8 @@ func DecodeObject(r io.RuneScanner, decodeKey, decodeVal func(io.RuneScanner) er
}
dec.posStackPush()
defer dec.posStackPop()
- dec.decodeObject(nil,
- func() {
+ if err := dec.decodeObject(nil,
+ func() *DecodeError {
dec.posStackPush()
defer dec.posStackPop()
l := dec.limitingScanner()
@@ -890,8 +896,9 @@ func DecodeObject(r io.RuneScanner, decodeKey, decodeVal func(io.RuneScanner) er
// TODO: Find a better Go type to use than `nil`.
dec.panicType("string", nil, fmt.Errorf("did not consume entire string"))
}
+ return nil
},
- func() {
+ func() *DecodeError {
dec.posStackPush()
defer dec.posStackPop()
t := dec.peekRuneType()
@@ -904,29 +911,36 @@ func DecodeObject(r io.RuneScanner, decodeKey, decodeVal func(io.RuneScanner) er
// 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) decodeObject(gTyp reflect.Type, decodeKey, decodeVal func()) {
+func (dec *Decoder) decodeObject(gTyp reflect.Type, decodeKey, decodeVal func() *DecodeError) *DecodeError {
dec.expectRuneType('{', jsonparse.RuneTypeObjectBeg, gTyp)
_, t := dec.readRune()
switch t {
case jsonparse.RuneTypeObjectEnd:
- return
+ return nil
case jsonparse.RuneTypeStringBeg:
decodeMember:
dec.unreadRune()
- decodeKey()
+ if err := decodeKey(); err != nil {
+ return err
+ }
dec.expectRune(':', jsonparse.RuneTypeObjectColon)
- decodeVal()
+ if err := decodeVal(); err != nil {
+ return err
+ }
_, t := dec.readRune()
switch t {
case jsonparse.RuneTypeObjectComma:
dec.expectRune('"', jsonparse.RuneTypeStringBeg)
goto decodeMember
case jsonparse.RuneTypeObjectEnd:
- return
+ return nil
default:
panic("should not happen")
}