Skip to content

Commit

Permalink
feat: Add NoValidateJSONMarshaler option (#527)
Browse files Browse the repository at this point in the history
  • Loading branch information
andeya committed Sep 11, 2023
1 parent a1555f1 commit 502d34c
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 22 deletions.
7 changes: 6 additions & 1 deletion api.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ type Config struct {

// ValidateString indicates decoder and encoder to valid string values: decoder will return errors
// when unescaped control chars(\u0000-\u001f) in the string value of JSON.
ValidateString bool
ValidateString bool

// NoValidateJSONMarshaler indicates that the encoder should not validate the output string
// after encoding the JSONMarshaler to JSON.
NoValidateJSONMarshaler bool
}

var (
Expand All @@ -87,6 +91,7 @@ var (
// ConfigFastest is the fastest config of APIs, aiming at speed.
ConfigFastest = Config{
NoQuoteTextMarshaler: true,
NoValidateJSONMarshaler: true,
}.Froze()
)

Expand Down
4 changes: 4 additions & 0 deletions encoder/encoder_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ const (
// before encoding it into JSON.
ValidateString Options = encoder.ValidateString

// NoValidateJSONMarshaler indicates that the encoder should not validate the output string
// after encoding the JSONMarshaler to JSON.
NoValidateJSONMarshaler Options = encoder.NoValidateJSONMarshaler

// CompatibleWithStd is used to be compatible with std encoder.
CompatibleWithStd Options = encoder.CompatibleWithStd
)
Expand Down
14 changes: 14 additions & 0 deletions encoder/encoder_compat.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const (
bitNoQuoteTextMarshaler
bitNoNullSliceOrMap
bitValidateString
bitNoValidateJSONMarshaler

// used for recursive compile
bitPointerValue = 63
Expand Down Expand Up @@ -72,6 +73,10 @@ const (
// ValidateString indicates that encoder should validate the input string
// before encoding it into JSON.
ValidateString Options = 1 << bitValidateString

// NoValidateJSONMarshaler indicates that the encoder should not validate the output string
// after encoding the JSONMarshaler to JSON.
NoValidateJSONMarshaler Options = 1 << bitNoValidateJSONMarshaler

// CompatibleWithStd is used to be compatible with std encoder.
CompatibleWithStd Options = SortMapKeys | EscapeHTML | CompactMarshaler
Expand Down Expand Up @@ -116,6 +121,15 @@ func (self *Encoder) SetValidateString(f bool) {
}
}

// SetNoValidateJSONMarshaler specifies if option NoValidateJSONMarshaler opens
func (self *Encoder) SetNoValidateJSONMarshaler(f bool) {
if f {
self.Opts |= NoValidateJSONMarshaler
} else {
self.Opts &= ^NoValidateJSONMarshaler
}
}

// SetCompactMarshaler specifies if option CompactMarshaler opens
func (self *Encoder) SetCompactMarshaler(f bool) {
if f {
Expand Down
14 changes: 14 additions & 0 deletions internal/encoder/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const (
bitNoQuoteTextMarshaler
bitNoNullSliceOrMap
bitValidateString
bitNoValidateJSONMarshaler

// used for recursive compile
bitPointerValue = 63
Expand Down Expand Up @@ -71,6 +72,10 @@ const (
// ValidateString indicates that encoder should validate the input string
// before encoding it into JSON.
ValidateString Options = 1 << bitValidateString

// NoValidateJSONMarshaler indicates that the encoder should not validate the output string
// after encoding the JSONMarshaler to JSON.
NoValidateJSONMarshaler Options = 1 << bitNoValidateJSONMarshaler

// CompatibleWithStd is used to be compatible with std encoder.
CompatibleWithStd Options = SortMapKeys | EscapeHTML | CompactMarshaler
Expand Down Expand Up @@ -115,6 +120,15 @@ func (self *Encoder) SetValidateString(f bool) {
}
}

// SetNoValidateJSONMarshaler specifies if option NoValidateJSONMarshaler opens
func (self *Encoder) SetNoValidateJSONMarshaler(f bool) {
if f {
self.Opts |= NoValidateJSONMarshaler
} else {
self.Opts &= ^NoValidateJSONMarshaler
}
}

// SetCompactMarshaler specifies if option CompactMarshaler opens
func (self *Encoder) SetCompactMarshaler(f bool) {
if f {
Expand Down
6 changes: 4 additions & 2 deletions internal/encoder/primitives.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ func encodeJsonMarshaler(buf *[]byte, val json.Marshaler, opt Options) error {
if opt & CompactMarshaler != 0 {
return compact(buf, ret)
}
if ok, s := Valid(ret); !ok {
return error_marshaler(ret, s)
if opt & NoValidateJSONMarshaler == 0 {
if ok, s := Valid(ret); !ok {
return error_marshaler(ret, s)
}
}
*buf = append(*buf, ret...)
return nil
Expand Down
41 changes: 22 additions & 19 deletions sonic.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ func (cfg Config) Froze() API {
if cfg.ValidateString {
api.encoderOpts |= encoder.ValidateString
}
if cfg.NoValidateJSONMarshaler {
api.encoderOpts |= encoder.NoValidateJSONMarshaler
}

// configure decoder options:
if cfg.UseInt64 {
Expand Down Expand Up @@ -139,23 +142,23 @@ func (cfg frozenConfig) Valid(data []byte) bool {
// Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is
// a compile option to set the depth of recursive compile for the nested struct type.
func Pretouch(vt reflect.Type, opts ...option.CompileOption) error {
if err := encoder.Pretouch(vt, opts...); err != nil {
return err
}
if err := decoder.Pretouch(vt, opts...); err != nil {
return err
}
// to pretouch the corresponding pointer type as well
if vt.Kind() == reflect.Ptr {
vt = vt.Elem()
} else {
vt = reflect.PtrTo(vt)
}
if err := encoder.Pretouch(vt, opts...); err != nil {
return err
}
if err := decoder.Pretouch(vt, opts...); err != nil {
return err
}
return nil
if err := encoder.Pretouch(vt, opts...); err != nil {
return err
}
if err := decoder.Pretouch(vt, opts...); err != nil {
return err
}
// to pretouch the corresponding pointer type as well
if vt.Kind() == reflect.Ptr {
vt = vt.Elem()
} else {
vt = reflect.PtrTo(vt)
}
if err := encoder.Pretouch(vt, opts...); err != nil {
return err
}
if err := decoder.Pretouch(vt, opts...); err != nil {
return err
}
return nil
}

0 comments on commit 502d34c

Please sign in to comment.