summaryrefslogtreecommitdiff
path: root/decode.go
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2023-02-10 19:02:38 -0700
committerLuke Shumaker <lukeshu@lukeshu.com>2023-02-10 21:49:02 -0700
commitaec0feb925614b0f878afa566b912d102ed9ccca (patch)
treedbb5d4e1746062a720652c87cf340ddbfdd80721 /decode.go
parentbdf0402da0d050f95a547da8a7a3752e9db0111b (diff)
decode: Have .peekRuneType() return a *DecodeError
Diffstat (limited to 'decode.go')
-rw-r--r--decode.go104
1 files changed, 81 insertions, 23 deletions
diff --git a/decode.go b/decode.go
index 73d15c5..15ab766 100644
--- a/decode.go
+++ b/decode.go
@@ -289,10 +289,11 @@ func (dec *Decoder) unreadRune() {
}
}
-func (dec *Decoder) peekRuneType() jsonparse.RuneType {
+//nolint:unparam // It will start returning errors soon.
+func (dec *Decoder) peekRuneType() (jsonparse.RuneType, *DecodeError) {
_, t := dec.readRune()
dec.unreadRune()
- return t
+ return t, nil
}
func (dec *Decoder) expectRune(ec rune, et jsonparse.RuneType) {
@@ -396,7 +397,10 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
typ := val.Type()
switch {
case val.CanAddr() && reflect.PointerTo(typ) == rawMessagePtrType:
- t := dec.peekRuneType()
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
var buf bytes.Buffer
if err := dec.scan(&buf); err != nil {
return err
@@ -405,7 +409,10 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
return dec.newTypeError(t.JSONType(), reflect.PointerTo(typ), err)
}
case val.CanAddr() && reflect.PointerTo(typ).Implements(decodableType):
- t := dec.peekRuneType()
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
obj := val.Addr().Interface().(Decodable)
return dec.withLimitingScanner(func(l io.RuneScanner) *DecodeError {
if err := obj.DecodeJSON(l); err != nil {
@@ -417,7 +424,10 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
return nil
})
case val.CanAddr() && reflect.PointerTo(typ).Implements(jsonUnmarshalerType):
- t := dec.peekRuneType()
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
var buf bytes.Buffer
if err := dec.scan(&buf); err != nil {
return err
@@ -494,7 +504,10 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
}
var buf strings.Builder
if typ == numberType {
- t := dec.peekRuneType()
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
if err := dec.scan(&buf); err != nil {
return err
}
@@ -511,8 +524,12 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
val.SetString(buf.String())
}
case reflect.Interface:
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
if typ.NumMethod() > 0 {
- return dec.newTypeError(dec.peekRuneType().JSONType(), typ, ErrDecodeNonEmptyInterface)
+ return dec.newTypeError(t.JSONType(), typ, ErrDecodeNonEmptyInterface)
}
// If the interface stores a pointer, try to use the type information of the pointer.
if !val.IsNil() && val.Elem().Kind() == reflect.Pointer {
@@ -533,11 +550,11 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
// in the loop) because the only way it's possible is if there's
// an interface in there, which'd break from the loop on its own.
//
- // ptr.CanSet() || dec.peekRuneType() != jsonparse.RuneTypeNullN
+ // ptr.CanSet() || t != jsonparse.RuneTypeNullN
//
// We only need the pointer itself to be settable if we're
// decoding null.
- if ptr.Elem() != val && (ptr.CanSet() || dec.peekRuneType() != jsonparse.RuneTypeNullN) {
+ if ptr.Elem() != val && (ptr.CanSet() || t != jsonparse.RuneTypeNullN) {
if err := dec.decode(ptr, false); err != nil {
return err
}
@@ -545,7 +562,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
}
}
// Couldn't get type information from a pointer; fall back to untyped mode.
- switch dec.peekRuneType() {
+ switch t {
case jsonparse.RuneTypeNullN:
if err := dec.decodeNull(); err != nil {
return err
@@ -600,7 +617,11 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
fmt.Errorf("json: cannot set embedded pointer to unexported struct: %v",
fVal.Type().Elem()))
}
- if dec.peekRuneType() != jsonparse.RuneTypeNullN {
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
+ if t != jsonparse.RuneTypeNullN {
if fVal.IsNil() {
fVal.Set(reflect.New(fVal.Type().Elem()))
}
@@ -610,7 +631,11 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
fVal = fVal.Field(idx)
}
if field.Quote {
- switch t := dec.peekRuneType(); t {
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
+ switch t {
case jsonparse.RuneTypeNullN:
if err := dec.decodeNull(); err != nil {
return err
@@ -647,7 +672,11 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
}
})
case reflect.Map:
- switch t := dec.peekRuneType(); t {
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
+ switch t {
case jsonparse.RuneTypeNullN:
if err := dec.decodeNull(); err != nil {
return err
@@ -713,12 +742,16 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
return dec.newTypeError(t.JSONType(), typ, nil)
}
case reflect.Slice:
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
switch {
- case typ.Elem().Kind() == reflect.Uint8 && !(dec.peekRuneType() == jsonparse.RuneTypeArrayBeg && (false ||
+ case typ.Elem().Kind() == reflect.Uint8 && !(t == jsonparse.RuneTypeArrayBeg && (false ||
reflect.PointerTo(typ.Elem()).Implements(decodableType) ||
reflect.PointerTo(typ.Elem()).Implements(jsonUnmarshalerType) ||
reflect.PointerTo(typ.Elem()).Implements(textUnmarshalerType))):
- switch t := dec.peekRuneType(); t {
+ switch t {
case jsonparse.RuneTypeNullN:
if err := dec.decodeNull(); err != nil {
return err
@@ -748,7 +781,7 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
return dec.newTypeError(t.JSONType(), typ, nil)
}
default:
- switch t := dec.peekRuneType(); t {
+ switch t {
case jsonparse.RuneTypeNullN:
if err := dec.decodeNull(); err != nil {
return err
@@ -810,7 +843,11 @@ func (dec *Decoder) decode(val reflect.Value, nullOK bool) (_err *DecodeError) {
val.Index(i).Set(reflect.Zero(typ.Elem()))
}
case reflect.Pointer:
- switch dec.peekRuneType() {
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
+ switch t {
case jsonparse.RuneTypeNullN:
if err := dec.decodeNull(); err != nil {
return err
@@ -843,7 +880,11 @@ func (dec *Decoder) scan(out fastio.RuneWriter) *DecodeError {
}
func (dec *Decoder) scanNumber(gTyp reflect.Type, out fastio.RuneWriter) *DecodeError {
- if t := dec.peekRuneType(); !t.IsNumber() {
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
+ if !t.IsNumber() {
return dec.newTypeError(t.JSONType(), gTyp, nil)
}
return dec.scan(out)
@@ -971,7 +1012,10 @@ func DecodeObject(r io.RuneScanner, decodeKey, decodeVal func(io.RuneScanner) er
func() *DecodeError {
dec.posStackPush()
defer dec.posStackPop()
- t := dec.peekRuneType()
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
return dec.withLimitingScanner(func(l io.RuneScanner) *DecodeError {
if err := decodeVal(l); err != nil {
// TODO: Find a better Go type to use than `nil`.
@@ -1052,7 +1096,10 @@ func DecodeArray(r io.RuneScanner, decodeMember func(r io.RuneScanner) error) (e
if err := dec.decodeArray(nil, func() *DecodeError {
dec.posStackPush()
defer dec.posStackPop()
- t := dec.peekRuneType()
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
return dec.withLimitingScanner(func(l io.RuneScanner) *DecodeError {
if err := decodeMember(l); err != nil {
// TODO: Find a better Go type to use than `nil`.
@@ -1144,12 +1191,20 @@ func (dec *Decoder) decodeString(gTyp reflect.Type, out fastio.RuneWriter) *Deco
rune(uhex[3])<<0
handleUnicode:
if utf16.IsSurrogate(c) {
- if dec.peekRuneType() != jsonparse.RuneTypeStringEsc {
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return err
+ }
+ if t != jsonparse.RuneTypeStringEsc {
_, _ = out.WriteRune(utf8.RuneError)
break
}
dec.expectRune('\\', jsonparse.RuneTypeStringEsc)
- if dec.peekRuneType() != jsonparse.RuneTypeStringEscU {
+ t, err = dec.peekRuneType()
+ if err != nil {
+ return err
+ }
+ if t != jsonparse.RuneTypeStringEscU {
_, _ = out.WriteRune(utf8.RuneError)
break
}
@@ -1215,7 +1270,10 @@ func (dec *Decoder) decodeNull() *DecodeError {
func (dec *Decoder) maybeDecodeNull(nullOK bool) (ok bool, err *DecodeError) {
if nullOK {
- t := dec.peekRuneType()
+ t, err := dec.peekRuneType()
+ if err != nil {
+ return true, err
+ }
if t == jsonparse.RuneTypeNullN {
return true, dec.decodeNull()
}