Skip to content

Commit

Permalink
Legacy support for v1
Browse files Browse the repository at this point in the history
  • Loading branch information
dsnet committed Dec 16, 2024
1 parent 94d5fea commit 3b61324
Show file tree
Hide file tree
Showing 15 changed files with 336 additions and 129 deletions.
33 changes: 28 additions & 5 deletions arshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ func Marshal(in any, opts ...Options) (out []byte, err error) {
xe := export.Encoder(enc)
xe.Flags.Set(jsonflags.OmitTopLevelNewline | 1)
err = marshalEncode(enc, in, &xe.Struct)
if err != nil && xe.Flags.Get(jsonflags.ReportLegacyErrorValues) {
return nil, internal.TransformMarshalError(err)
}
return bytes.Clone(xe.Buf), err
}

Expand All @@ -178,7 +181,11 @@ func MarshalWrite(out io.Writer, in any, opts ...Options) (err error) {
defer export.PutStreamingEncoder(enc)
xe := export.Encoder(enc)
xe.Flags.Set(jsonflags.OmitTopLevelNewline | 1)
return marshalEncode(enc, in, &xe.Struct)
err = marshalEncode(enc, in, &xe.Struct)
if err != nil && xe.Flags.Get(jsonflags.ReportLegacyErrorValues) {
return internal.TransformMarshalError(err)
}
return err
}

// MarshalEncode serializes a Go value into an [jsontext.Encoder] according to
Expand All @@ -192,7 +199,11 @@ func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) {
mo.Join(opts...)
xe := export.Encoder(out)
mo.CopyCoderOptions(&xe.Struct)
return marshalEncode(out, in, mo)
err = marshalEncode(out, in, mo)
if err != nil && xe.Flags.Get(jsonflags.ReportLegacyErrorValues) {
return internal.TransformMarshalError(err)
}
return err
}

func marshalEncode(out *jsontext.Encoder, in any, mo *jsonopts.Struct) (err error) {
Expand Down Expand Up @@ -384,7 +395,11 @@ func Unmarshal(in []byte, out any, opts ...Options) (err error) {
dec := export.GetBufferedDecoder(in, opts...)
defer export.PutBufferedDecoder(dec)
xd := export.Decoder(dec)
return unmarshalFull(dec, out, &xd.Struct)
err = unmarshalFull(dec, out, &xd.Struct)
if err != nil && xd.Flags.Get(jsonflags.ReportLegacyErrorValues) {
return internal.TransformUnmarshalError(err)
}
return err
}

// UnmarshalRead deserializes a Go value from an [io.Reader] according to the
Expand All @@ -397,7 +412,11 @@ func UnmarshalRead(in io.Reader, out any, opts ...Options) (err error) {
dec := export.GetStreamingDecoder(in, opts...)
defer export.PutStreamingDecoder(dec)
xd := export.Decoder(dec)
return unmarshalFull(dec, out, &xd.Struct)
err = unmarshalFull(dec, out, &xd.Struct)
if err != nil && xd.Flags.Get(jsonflags.ReportLegacyErrorValues) {
return internal.TransformUnmarshalError(err)
}
return err
}

func unmarshalFull(in *jsontext.Decoder, out any, uo *jsonopts.Struct) error {
Expand Down Expand Up @@ -425,7 +444,11 @@ func UnmarshalDecode(in *jsontext.Decoder, out any, opts ...Options) (err error)
uo.Join(opts...)
xd := export.Decoder(in)
uo.CopyCoderOptions(&xd.Struct)
return unmarshalDecode(in, out, uo)
err = unmarshalDecode(in, out, uo)
if err != nil && uo.Flags.Get(jsonflags.ReportLegacyErrorValues) {
return internal.TransformUnmarshalError(err)
}
return err
}

var errNonNilReference = errors.New("value must be passed as a non-nil pointer reference")
Expand Down
4 changes: 4 additions & 0 deletions arshal_any.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"reflect"
"strconv"

"github.com/go-json-experiment/json/internal"
"github.com/go-json-experiment/json/internal/jsonflags"
"github.com/go-json-experiment/json/internal/jsonopts"
"github.com/go-json-experiment/json/internal/jsonwire"
Expand Down Expand Up @@ -71,6 +72,9 @@ func unmarshalValueAny(dec *jsontext.Decoder, uo *jsonopts.Struct) (any, error)
}
return makeString(xd.StringCache, val), nil
case '0':
if uo.Flags.Get(jsonflags.UnmarshalAnyWithRawNumber) {
return internal.RawNumberOf(val), nil
}
fv, ok := jsonwire.ParseFloat(val, 64)
if !ok && uo.Flags.Get(jsonflags.RejectFloatOverflow) {
return nil, newUnmarshalErrorAfter(dec, float64Type, strconv.ErrRange)
Expand Down
41 changes: 30 additions & 11 deletions arshal_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"strconv"
"sync"

"github.com/go-json-experiment/json/internal"
"github.com/go-json-experiment/json/internal/jsonflags"
"github.com/go-json-experiment/json/internal/jsonopts"
"github.com/go-json-experiment/json/internal/jsonwire"
Expand Down Expand Up @@ -158,7 +159,9 @@ func makeBoolArshaler(t reflect.Type) *arshaler {
k := tok.Kind()
switch k {
case 'n':
va.SetBool(false)
if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
va.SetBool(false)
}
return nil
case 't', 'f':
if !uo.Flags.Get(jsonflags.StringifyBoolsAndStrings) {
Expand Down Expand Up @@ -230,7 +233,9 @@ func makeStringArshaler(t reflect.Type) *arshaler {
k := val.Kind()
switch k {
case 'n':
va.SetString("")
if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
va.SetString("")
}
return nil
case '"':
val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
Expand Down Expand Up @@ -352,7 +357,9 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler {
k := val.Kind()
switch k {
case 'n':
va.SetZero()
if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) || va.Kind() == reflect.Slice {
va.SetZero()
}
return nil
case '"':
val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
Expand Down Expand Up @@ -437,7 +444,9 @@ func makeIntArshaler(t reflect.Type) *arshaler {
k := val.Kind()
switch k {
case 'n':
va.SetInt(0)
if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
va.SetInt(0)
}
return nil
case '"':
if !uo.Flags.Get(jsonflags.StringifyNumbers) {
Expand Down Expand Up @@ -517,7 +526,9 @@ func makeUintArshaler(t reflect.Type) *arshaler {
k := val.Kind()
switch k {
case 'n':
va.SetUint(0)
if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
va.SetUint(0)
}
return nil
case '"':
if !uo.Flags.Get(jsonflags.StringifyNumbers) {
Expand Down Expand Up @@ -607,7 +618,9 @@ func makeFloatArshaler(t reflect.Type) *arshaler {
k := val.Kind()
switch k {
case 'n':
va.SetFloat(0)
if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
va.SetFloat(0)
}
return nil
case '"':
val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim())
Expand Down Expand Up @@ -958,7 +971,7 @@ func makeStructArshaler(t reflect.Type) *arshaler {
return newInvalidFormatError(enc, t, mo.Format)
}
once.Do(init)
if errInit != nil {
if errInit != nil && !mo.Flags.Get(jsonflags.IgnoreStructErrors) {
return newMarshalErrorBefore(enc, errInit.GoType, errInit.Err)
}
if err := enc.WriteToken(jsontext.ObjectStart); err != nil {
Expand Down Expand Up @@ -1030,7 +1043,7 @@ func makeStructArshaler(t reflect.Type) *arshaler {

// Append the token to the output and to the state machine.
n0 := len(b) // offset before calling AppendQuote
if !xe.Flags.Get(jsonflags.EscapeForHTML | jsonflags.EscapeForJS) {
if !xe.Flags.Get(jsonflags.EscapeForHTML | jsonflags.EscapeForJS | jsonflags.EscapeInvalidUTF8) {
b = append(b, f.quotedName...)
} else {
b, _ = jsonwire.AppendQuote(b, f.name, &xe.Flags)
Expand Down Expand Up @@ -1130,7 +1143,7 @@ func makeStructArshaler(t reflect.Type) *arshaler {
return nil
case '{':
once.Do(init)
if errInit != nil {
if errInit != nil && !uo.Flags.Get(jsonflags.IgnoreStructErrors) {
return newUnmarshalErrorAfter(dec, errInit.GoType, errInit.Err)
}
var seenIdxs uintSet
Expand Down Expand Up @@ -1463,7 +1476,9 @@ func makeArrayArshaler(t reflect.Type) *arshaler {
k := tok.Kind()
switch k {
case 'n':
va.SetZero()
if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) {
va.SetZero()
}
return nil
case '[':
once.Do(init)
Expand Down Expand Up @@ -1629,7 +1644,11 @@ func makeInterfaceArshaler(t reflect.Type) *arshaler {
case '"':
v = newAddressableValue(stringType)
case '0':
v = newAddressableValue(float64Type)
if uo.Flags.Get(jsonflags.UnmarshalAnyWithRawNumber) {
v = addressableValue{reflect.ValueOf(internal.NewRawNumber()).Elem()}
} else {
v = newAddressableValue(float64Type)
}
case '{':
v = newAddressableValue(mapStringAnyType)
case '[':
Expand Down
Loading

0 comments on commit 3b61324

Please sign in to comment.