summaryrefslogtreecommitdiff
path: root/compat/json/compat.go
diff options
context:
space:
mode:
Diffstat (limited to 'compat/json/compat.go')
-rw-r--r--compat/json/compat.go45
1 files changed, 42 insertions, 3 deletions
diff --git a/compat/json/compat.go b/compat/json/compat.go
index 78a9d5f..b26914b 100644
--- a/compat/json/compat.go
+++ b/compat/json/compat.go
@@ -8,7 +8,9 @@ import (
"bufio"
"bytes"
"encoding/json"
+ "errors"
"io"
+ "strconv"
"git.lukeshu.com/go/lowmemjson"
)
@@ -19,7 +21,7 @@ type (
RawMessage = json.RawMessage
// low-level decode errors
- SyntaxError = lowmemjson.SyntaxError
+ //SyntaxError = lowmemjson.DecodeSyntaxError // expose a field
UnmarshalFieldError = json.UnmarshalFieldError
UnmarshalTypeError = json.UnmarshalTypeError // lowmemjson.DecodeTypeError
@@ -28,7 +30,7 @@ type (
// marshal errors
InvalidUTF8Error = json.InvalidUTF8Error
- MarshalerError = json.MarshalerError
+ MarshalerError = lowmemjson.EncodeMethodError // expose a field
UnsupportedTypeError = json.UnsupportedTypeError
UnsupportedValueError = json.UnsupportedValueError
)
@@ -92,7 +94,7 @@ func Valid(data []byte) bool {
}
func Unmarshal(data []byte, ptr any) error {
- return lowmemjson.Decode(bytes.NewReader(data), ptr)
+ return NewDecoder(bytes.NewReader(data)).Decode(ptr)
}
/////////////////////////////////////////////////////////////////////
@@ -113,6 +115,43 @@ func NewDecoder(r io.Reader) *Decoder {
}
}
+func (dec *Decoder) Decode(ptr any) error {
+ err := dec.Decoder.Decode(ptr)
+ if derr, ok := err.(*lowmemjson.DecodeError); ok {
+ switch terr := derr.Err.(type) {
+ case *lowmemjson.DecodeSyntaxError:
+ err = &SyntaxError{
+ msg: terr.Err.Error(),
+ Offset: terr.Offset,
+ }
+ case *lowmemjson.DecodeTypeError:
+ if typeErr, ok := terr.Err.(*json.UnmarshalTypeError); ok {
+ err = &UnmarshalTypeError{
+ Value: typeErr.Value,
+ Type: typeErr.Type,
+ Offset: typeErr.Offset,
+ Struct: derr.FieldParent,
+ Field: derr.FieldName,
+ }
+ } else if _, isArgErr := terr.Err.(*lowmemjson.DecodeArgumentError); terr.Err != nil &&
+ !isArgErr &&
+ !errors.Is(terr.Err, strconv.ErrSyntax) &&
+ !errors.Is(terr.Err, strconv.ErrRange) {
+ err = terr.Err
+ } else {
+ err = &UnmarshalTypeError{
+ Value: terr.JSONType,
+ Type: terr.GoType,
+ Offset: terr.Offset,
+ Struct: derr.FieldParent,
+ Field: derr.FieldName,
+ }
+ }
+ }
+ }
+ return err
+}
+
func (dec *Decoder) Buffered() io.Reader {
dat, _ := dec.buf.Peek(dec.buf.Buffered())
return bytes.NewReader(dat)