mirror of
https://github.com/ii64/sonic.git
synced 2026-06-21 00:46:43 +08:00
feat: fallback on unsupported go versions (#358)
* feat: fallback api on unsupported go version * add compact test * not support go version <= 1.14
This commit is contained in:
parent
e7ac2f25fc
commit
f87d87de7a
14 changed files with 147 additions and 152 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
A blazingly fast JSON serializing & deserializing library, accelerated by JIT (just-in-time compiling) and SIMD (single-instruction-multiple-data).
|
A blazingly fast JSON serializing & deserializing library, accelerated by JIT (just-in-time compiling) and SIMD (single-instruction-multiple-data).
|
||||||
|
|
||||||
## Requirement
|
## Requirement
|
||||||
- Go 1.15/1.16/1.17/1.18/1.19
|
- Go 1.15~1.20
|
||||||
- Linux/MacOS/Windows
|
- Linux/MacOS/Windows
|
||||||
- Amd64 ARCH
|
- Amd64 ARCH
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//go:build amd64
|
// +build amd64,go1.15,!go1.21
|
||||||
// +build amd64
|
|
||||||
|
|
||||||
package ast
|
package ast
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build amd64
|
// +build amd64,go1.15,!go1.21
|
||||||
// +build amd64
|
|
||||||
|
|
||||||
package ast
|
package ast
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build !amd64
|
// +build !amd64 go1.21
|
||||||
// +build !amd64
|
|
||||||
|
|
||||||
package ast
|
package ast
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// +build go1.15,!go1.20
|
// +build !go1.20
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build !amd64
|
// +build !amd64 go1.21
|
||||||
// +build !amd64
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
|
@ -120,7 +119,6 @@ func (cfg frozenConfig) Valid(data []byte) bool {
|
||||||
return json.Valid(data)
|
return json.Valid(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Pretouch compiles vt ahead-of-time to avoid JIT compilation on-the-fly, in
|
// Pretouch compiles vt ahead-of-time to avoid JIT compilation on-the-fly, in
|
||||||
// order to reduce the first-hit latency at **amd64** Arch.
|
// order to reduce the first-hit latency at **amd64** Arch.
|
||||||
// Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is
|
// Opts are the compile options, for example, "option.WithCompileRecursiveDepth" is
|
||||||
|
|
|
||||||
137
compat_test.go
137
compat_test.go
|
|
@ -1,6 +1,3 @@
|
||||||
//go:build !amd64
|
|
||||||
// +build !amd64
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2022 ByteDance Inc.
|
* Copyright 2022 ByteDance Inc.
|
||||||
*
|
*
|
||||||
|
|
@ -20,12 +17,146 @@
|
||||||
package sonic
|
package sonic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
`bytes`
|
||||||
|
`encoding/json`
|
||||||
`reflect`
|
`reflect`
|
||||||
`testing`
|
`testing`
|
||||||
|
|
||||||
`github.com/bytedance/sonic/option`
|
`github.com/bytedance/sonic/option`
|
||||||
|
`github.com/stretchr/testify/require`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestCompatUnmarshalStd(t *testing.T) {
|
||||||
|
var sobj = map[string]interface{}{}
|
||||||
|
var jobj = map[string]interface{}{}
|
||||||
|
var data = []byte(`{"a":1.00000001E-10}`)
|
||||||
|
var str = string(data)
|
||||||
|
serr := ConfigStd.UnmarshalFromString(str, &sobj)
|
||||||
|
jerr := json.Unmarshal(data, &jobj)
|
||||||
|
require.Equal(t, jerr, serr)
|
||||||
|
require.Equal(t, jobj, sobj)
|
||||||
|
data[2] = '0'
|
||||||
|
require.Equal(t, jobj, sobj)
|
||||||
|
|
||||||
|
sobj = map[string]interface{}{}
|
||||||
|
jobj = map[string]interface{}{}
|
||||||
|
data = []byte(`{"a":1}`)
|
||||||
|
cfg := Config{
|
||||||
|
UseNumber: true,
|
||||||
|
}.Froze()
|
||||||
|
serr = cfg.Unmarshal(data, &sobj)
|
||||||
|
dec := json.NewDecoder(bytes.NewBuffer(data))
|
||||||
|
dec.UseNumber()
|
||||||
|
jerr = dec.Decode(&jobj)
|
||||||
|
require.Equal(t, jerr, serr)
|
||||||
|
require.Equal(t, jobj, sobj)
|
||||||
|
|
||||||
|
x := struct{
|
||||||
|
A json.Number
|
||||||
|
B json.Number
|
||||||
|
}{}
|
||||||
|
y := struct{
|
||||||
|
A json.Number
|
||||||
|
B json.Number
|
||||||
|
}{}
|
||||||
|
data = []byte(`{"A":"1", "C":-1, "B":1}`)
|
||||||
|
cfg = Config{
|
||||||
|
DisallowUnknownFields: true,
|
||||||
|
}.Froze()
|
||||||
|
serr = cfg.Unmarshal(data, &x)
|
||||||
|
dec = json.NewDecoder(bytes.NewBuffer(data))
|
||||||
|
dec.UseNumber()
|
||||||
|
dec.DisallowUnknownFields()
|
||||||
|
jerr = dec.Decode(&y)
|
||||||
|
require.Equal(t, jerr, serr)
|
||||||
|
// require.Equal(t, y, x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompatMarshalStd(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
var obj = map[string]interface{}{
|
||||||
|
"c": json.RawMessage(" [ \"<&>\" ] "),
|
||||||
|
"b": json.RawMessage(" [ ] "),
|
||||||
|
}
|
||||||
|
sout, serr := ConfigStd.Marshal(obj)
|
||||||
|
jout, jerr := json.Marshal(obj)
|
||||||
|
require.Equal(t, jerr, serr)
|
||||||
|
require.Equal(t, string(jout), string(sout))
|
||||||
|
|
||||||
|
obj = map[string]interface{}{
|
||||||
|
"a": json.RawMessage(" [} "),
|
||||||
|
}
|
||||||
|
sout, serr = ConfigStd.Marshal(obj)
|
||||||
|
jout, jerr = json.Marshal(obj)
|
||||||
|
require.NotNil(t, jerr)
|
||||||
|
require.NotNil(t, serr)
|
||||||
|
require.Equal(t, string(jout), string(sout))
|
||||||
|
|
||||||
|
obj = map[string]interface{}{
|
||||||
|
"a": json.RawMessage("1"),
|
||||||
|
}
|
||||||
|
sout, serr = ConfigStd.MarshalIndent(obj, "xxxx", " ")
|
||||||
|
jout, jerr = json.MarshalIndent(obj, "xxxx", " ")
|
||||||
|
require.Equal(t, jerr, serr)
|
||||||
|
require.Equal(t, string(jout), string(sout))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompatEncoderStd(t *testing.T) {
|
||||||
|
var o = map[string]interface{}{
|
||||||
|
"a": "<>",
|
||||||
|
"b": json.RawMessage(" [ ] "),
|
||||||
|
}
|
||||||
|
var w1 = bytes.NewBuffer(nil)
|
||||||
|
var w2 = bytes.NewBuffer(nil)
|
||||||
|
var enc1 = json.NewEncoder(w1)
|
||||||
|
var enc2 = ConfigStd.NewEncoder(w2)
|
||||||
|
|
||||||
|
require.Nil(t, enc1.Encode(o))
|
||||||
|
require.Nil(t, enc2.Encode(o))
|
||||||
|
require.Equal(t, w1.String(), w2.String())
|
||||||
|
|
||||||
|
enc1.SetEscapeHTML(true)
|
||||||
|
enc2.SetEscapeHTML(true)
|
||||||
|
enc1.SetIndent("\n", " ")
|
||||||
|
enc2.SetIndent("\n", " ")
|
||||||
|
require.Nil(t, enc1.Encode(o))
|
||||||
|
require.Nil(t, enc2.Encode(o))
|
||||||
|
require.Equal(t, w1.String(), w2.String())
|
||||||
|
|
||||||
|
enc1.SetEscapeHTML(false)
|
||||||
|
enc2.SetEscapeHTML(false)
|
||||||
|
enc1.SetIndent("", "")
|
||||||
|
enc2.SetIndent("", "")
|
||||||
|
require.Nil(t, enc1.Encode(o))
|
||||||
|
require.Nil(t, enc2.Encode(o))
|
||||||
|
require.Equal(t, w1.String(), w2.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCompatDecoderStd(t *testing.T) {
|
||||||
|
var o1 = map[string]interface{}{}
|
||||||
|
var o2 = map[string]interface{}{}
|
||||||
|
var s = `{"a":"b"} {"1":"2"} a {}`
|
||||||
|
var w1 = bytes.NewBuffer([]byte(s))
|
||||||
|
var w2 = bytes.NewBuffer([]byte(s))
|
||||||
|
var enc1 = json.NewDecoder(w1)
|
||||||
|
var enc2 = ConfigStd.NewDecoder(w2)
|
||||||
|
|
||||||
|
require.Equal(t, enc1.More(), enc2.More())
|
||||||
|
require.Nil(t, enc1.Decode(&o1))
|
||||||
|
require.Nil(t, enc2.Decode(&o2))
|
||||||
|
require.Equal(t, w1.String(), w2.String())
|
||||||
|
|
||||||
|
require.Equal(t, enc1.More(), enc2.More())
|
||||||
|
require.Nil(t, enc1.Decode(&o1))
|
||||||
|
require.Nil(t, enc2.Decode(&o2))
|
||||||
|
require.Equal(t, w1.String(), w2.String())
|
||||||
|
|
||||||
|
require.Equal(t, enc1.More(), enc2.More())
|
||||||
|
require.NotNil(t, enc1.Decode(&o1))
|
||||||
|
require.NotNil(t, enc2.Decode(&o2))
|
||||||
|
require.Equal(t, w1.String(), w2.String())
|
||||||
|
}
|
||||||
|
|
||||||
func TestPretouch(t *testing.T) {
|
func TestPretouch(t *testing.T) {
|
||||||
var v map[string]interface{}
|
var v map[string]interface{}
|
||||||
if err := Pretouch(reflect.TypeOf(v)); err != nil {
|
if err := Pretouch(reflect.TypeOf(v)); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// +build amd64
|
// +build amd64,go1.15,!go1.21
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
//go:build amd64
|
// +build amd64,go1.15,!go1.21
|
||||||
// +build amd64
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// +build amd64
|
// +build amd64,go1.15,!go1.21
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
|
|
||||||
|
|
@ -82,35 +82,6 @@ func TestCompatMarshalDefault(t *testing.T){
|
||||||
require.Equal(t, string(jout), string(sout))
|
require.Equal(t, string(jout), string(sout))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompatMarshalStd(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
var obj = map[string]interface{}{
|
|
||||||
"c": json.RawMessage(" [ \"<&>\" ] "),
|
|
||||||
"b": json.RawMessage(" [ ] "),
|
|
||||||
}
|
|
||||||
sout, serr := sonic.ConfigStd.Marshal(obj)
|
|
||||||
jout, jerr := json.Marshal(obj)
|
|
||||||
require.Equal(t, jerr, serr)
|
|
||||||
require.Equal(t, string(jout), string(sout))
|
|
||||||
|
|
||||||
obj = map[string]interface{}{
|
|
||||||
"a": json.RawMessage(" [} "),
|
|
||||||
}
|
|
||||||
sout, serr = sonic.ConfigStd.Marshal(obj)
|
|
||||||
jout, jerr = json.Marshal(obj)
|
|
||||||
require.NotNil(t, jerr)
|
|
||||||
require.NotNil(t, serr)
|
|
||||||
require.Equal(t, string(jout), string(sout))
|
|
||||||
|
|
||||||
obj = map[string]interface{}{
|
|
||||||
"a": json.RawMessage("1"),
|
|
||||||
}
|
|
||||||
sout, serr = sonic.ConfigStd.MarshalIndent(obj, "xxxx", " ")
|
|
||||||
jout, jerr = json.MarshalIndent(obj, "xxxx", " ")
|
|
||||||
require.Equal(t, jerr, serr)
|
|
||||||
require.Equal(t, string(jout), string(sout))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCompatUnmarshalDefault(t *testing.T) {
|
func TestCompatUnmarshalDefault(t *testing.T) {
|
||||||
var sobj = map[string]interface{}{}
|
var sobj = map[string]interface{}{}
|
||||||
var jobj = map[string]interface{}{}
|
var jobj = map[string]interface{}{}
|
||||||
|
|
@ -130,52 +101,6 @@ func TestCompatUnmarshalDefault(t *testing.T) {
|
||||||
require.Equal(t, y, x)
|
require.Equal(t, y, x)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompatUnmarshalStd(t *testing.T) {
|
|
||||||
var sobj = map[string]interface{}{}
|
|
||||||
var jobj = map[string]interface{}{}
|
|
||||||
var data = []byte(`{"a":1.00000001E-10}`)
|
|
||||||
var str = string(data)
|
|
||||||
serr := sonic.ConfigStd.UnmarshalFromString(str, &sobj)
|
|
||||||
jerr := json.Unmarshal(data, &jobj)
|
|
||||||
require.Equal(t, jerr, serr)
|
|
||||||
require.Equal(t, jobj, sobj)
|
|
||||||
data[2] = '0'
|
|
||||||
require.Equal(t, jobj, sobj)
|
|
||||||
|
|
||||||
sobj = map[string]interface{}{}
|
|
||||||
jobj = map[string]interface{}{}
|
|
||||||
data = []byte(`{"a":1}`)
|
|
||||||
cfg := sonic.Config{
|
|
||||||
UseNumber: true,
|
|
||||||
}.Froze()
|
|
||||||
serr = cfg.Unmarshal(data, &sobj)
|
|
||||||
dec := json.NewDecoder(bytes.NewBuffer(data))
|
|
||||||
dec.UseNumber()
|
|
||||||
jerr = dec.Decode(&jobj)
|
|
||||||
require.Equal(t, jerr, serr)
|
|
||||||
require.Equal(t, jobj, sobj)
|
|
||||||
|
|
||||||
x := struct{
|
|
||||||
A json.Number
|
|
||||||
B json.Number
|
|
||||||
}{}
|
|
||||||
y := struct{
|
|
||||||
A json.Number
|
|
||||||
B json.Number
|
|
||||||
}{}
|
|
||||||
data = []byte(`{"A":"1", "C":-1, "B":1}`)
|
|
||||||
cfg = sonic.Config{
|
|
||||||
DisallowUnknownFields: true,
|
|
||||||
}.Froze()
|
|
||||||
serr = cfg.Unmarshal(data, &x)
|
|
||||||
dec = json.NewDecoder(bytes.NewBuffer(data))
|
|
||||||
dec.UseNumber()
|
|
||||||
dec.DisallowUnknownFields()
|
|
||||||
jerr = dec.Decode(&y)
|
|
||||||
require.Equal(t, jerr, serr)
|
|
||||||
// require.Equal(t, y, x)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCompatEncoderDefault(t *testing.T) {
|
func TestCompatEncoderDefault(t *testing.T) {
|
||||||
var o = map[string]interface{}{
|
var o = map[string]interface{}{
|
||||||
"a": "<>",
|
"a": "<>",
|
||||||
|
|
@ -207,62 +132,6 @@ func TestCompatEncoderDefault(t *testing.T) {
|
||||||
require.Equal(t, w1.String(), w2.String())
|
require.Equal(t, w1.String(), w2.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompatEncoderStd(t *testing.T) {
|
|
||||||
var o = map[string]interface{}{
|
|
||||||
"a": "<>",
|
|
||||||
"b": json.RawMessage(" [ ] "),
|
|
||||||
}
|
|
||||||
var w1 = bytes.NewBuffer(nil)
|
|
||||||
var w2 = bytes.NewBuffer(nil)
|
|
||||||
var enc1 = json.NewEncoder(w1)
|
|
||||||
var enc2 = sonic.ConfigStd.NewEncoder(w2)
|
|
||||||
|
|
||||||
require.Nil(t, enc1.Encode(o))
|
|
||||||
require.Nil(t, enc2.Encode(o))
|
|
||||||
require.Equal(t, w1.String(), w2.String())
|
|
||||||
|
|
||||||
enc1.SetEscapeHTML(true)
|
|
||||||
enc2.SetEscapeHTML(true)
|
|
||||||
enc1.SetIndent("\n", " ")
|
|
||||||
enc2.SetIndent("\n", " ")
|
|
||||||
require.Nil(t, enc1.Encode(o))
|
|
||||||
require.Nil(t, enc2.Encode(o))
|
|
||||||
require.Equal(t, w1.String(), w2.String())
|
|
||||||
|
|
||||||
enc1.SetEscapeHTML(false)
|
|
||||||
enc2.SetEscapeHTML(false)
|
|
||||||
enc1.SetIndent("", "")
|
|
||||||
enc2.SetIndent("", "")
|
|
||||||
require.Nil(t, enc1.Encode(o))
|
|
||||||
require.Nil(t, enc2.Encode(o))
|
|
||||||
require.Equal(t, w1.String(), w2.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCompatDecoderStd(t *testing.T) {
|
|
||||||
var o1 = map[string]interface{}{}
|
|
||||||
var o2 = map[string]interface{}{}
|
|
||||||
var s = `{"a":"b"} {"1":"2"} a {}`
|
|
||||||
var w1 = bytes.NewBuffer([]byte(s))
|
|
||||||
var w2 = bytes.NewBuffer([]byte(s))
|
|
||||||
var enc1 = json.NewDecoder(w1)
|
|
||||||
var enc2 = sonic.ConfigStd.NewDecoder(w2)
|
|
||||||
|
|
||||||
require.Equal(t, enc1.More(), enc2.More())
|
|
||||||
require.Nil(t, enc1.Decode(&o1))
|
|
||||||
require.Nil(t, enc2.Decode(&o2))
|
|
||||||
require.Equal(t, w1.String(), w2.String())
|
|
||||||
|
|
||||||
require.Equal(t, enc1.More(), enc2.More())
|
|
||||||
require.Nil(t, enc1.Decode(&o1))
|
|
||||||
require.Nil(t, enc2.Decode(&o2))
|
|
||||||
require.Equal(t, w1.String(), w2.String())
|
|
||||||
|
|
||||||
require.Equal(t, enc1.More(), enc2.More())
|
|
||||||
require.NotNil(t, enc1.Decode(&o1))
|
|
||||||
require.NotNil(t, enc2.Decode(&o2))
|
|
||||||
require.Equal(t, w1.String(), w2.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCompatDecoderDefault(t *testing.T) {
|
func TestCompatDecoderDefault(t *testing.T) {
|
||||||
var o1 = map[string]interface{}{}
|
var o1 = map[string]interface{}{}
|
||||||
var o2 = map[string]interface{}{}
|
var o2 = map[string]interface{}{}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// +build amd64
|
// +build amd64,go1.15,!go1.21
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
|
|
||||||
2
sonic.go
2
sonic.go
|
|
@ -1,4 +1,4 @@
|
||||||
// +build amd64
|
// +build amd64,go1.15,!go1.21
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// +build amd64
|
// +build amd64,go1.15,!go1.21
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2021 ByteDance Inc.
|
* Copyright 2021 ByteDance Inc.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue