mirror of
https://github.com/json-iterator/go.git
synced 2025-04-20 11:28:49 +02:00
Any Get will never return nil
This commit is contained in:
parent
9abc2f52b0
commit
85edb698c8
@ -1,7 +1,10 @@
|
|||||||
package jsoniter
|
package jsoniter
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
type Any interface {
|
type Any interface {
|
||||||
LastError() error
|
LastError() error
|
||||||
|
ValueType() ValueType
|
||||||
ToBool() bool
|
ToBool() bool
|
||||||
ToInt() int
|
ToInt() int
|
||||||
ToInt32() int32
|
ToInt32() int32
|
||||||
@ -26,7 +29,7 @@ type Any interface {
|
|||||||
type baseAny struct{}
|
type baseAny struct{}
|
||||||
|
|
||||||
func (any *baseAny) Get(path ...interface{}) Any {
|
func (any *baseAny) Get(path ...interface{}) Any {
|
||||||
return &invalidAny{}
|
return &invalidAny{baseAny{}, fmt.Errorf("Get %v from simple value", path)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *baseAny) Size() int {
|
func (any *baseAny) Size() int {
|
||||||
|
@ -2,6 +2,7 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type arrayLazyAny struct {
|
type arrayLazyAny struct {
|
||||||
@ -13,6 +14,10 @@ type arrayLazyAny struct {
|
|||||||
remaining []byte
|
remaining []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (any *arrayLazyAny) ValueType() ValueType {
|
||||||
|
return Array
|
||||||
|
}
|
||||||
|
|
||||||
func (any *arrayLazyAny) Parse() *Iterator {
|
func (any *arrayLazyAny) Parse() *Iterator {
|
||||||
iter := any.iter
|
iter := any.iter
|
||||||
if iter == nil {
|
if iter == nil {
|
||||||
@ -176,12 +181,20 @@ func (any *arrayLazyAny) Get(path ...interface{}) Any {
|
|||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
return any
|
return any
|
||||||
}
|
}
|
||||||
if len(path) == 1 {
|
var element Any
|
||||||
idx := path[0].(int)
|
idx, ok := path[0].(int)
|
||||||
return any.fillCacheUntil(idx)
|
if ok {
|
||||||
|
element = any.fillCacheUntil(idx)
|
||||||
|
if element == nil {
|
||||||
|
element = &invalidAny{baseAny{}, fmt.Errorf("%v not found in %v", idx, any.cache)}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
idx := path[0].(int)
|
element = &invalidAny{baseAny{}, fmt.Errorf("%v not found in %v", idx, any.cache)}
|
||||||
return any.fillCacheUntil(idx).Get(path[1:]...)
|
}
|
||||||
|
if len(path) == 1 {
|
||||||
|
return element
|
||||||
|
} else {
|
||||||
|
return element.Get(path[1:]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,10 @@ func (any *trueAny) GetInterface() interface{} {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (any *trueAny) ValueType() ValueType {
|
||||||
|
return Bool
|
||||||
|
}
|
||||||
|
|
||||||
type falseAny struct {
|
type falseAny struct {
|
||||||
baseAny
|
baseAny
|
||||||
}
|
}
|
||||||
@ -95,3 +99,7 @@ func (any *falseAny) Parse() *Iterator {
|
|||||||
func (any *falseAny) GetInterface() interface{} {
|
func (any *falseAny) GetInterface() interface{} {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (any *falseAny) ValueType() ValueType {
|
||||||
|
return Bool
|
||||||
|
}
|
||||||
|
@ -22,6 +22,10 @@ func (any *floatLazyAny) Parse() *Iterator {
|
|||||||
return iter
|
return iter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (any *floatLazyAny) ValueType() ValueType {
|
||||||
|
return Number
|
||||||
|
}
|
||||||
|
|
||||||
func (any *floatLazyAny) fillCache() {
|
func (any *floatLazyAny) fillCache() {
|
||||||
if any.err != nil {
|
if any.err != nil {
|
||||||
return
|
return
|
||||||
|
@ -14,6 +14,10 @@ type intLazyAny struct {
|
|||||||
cache int64
|
cache int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (any *intLazyAny) ValueType() ValueType {
|
||||||
|
return Number
|
||||||
|
}
|
||||||
|
|
||||||
func (any *intLazyAny) Parse() *Iterator {
|
func (any *intLazyAny) Parse() *Iterator {
|
||||||
iter := any.iter
|
iter := any.iter
|
||||||
if iter == nil {
|
if iter == nil {
|
||||||
@ -91,6 +95,10 @@ func (any *intAny) LastError() error {
|
|||||||
return any.err
|
return any.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (any *intAny) ValueType() ValueType {
|
||||||
|
return Number
|
||||||
|
}
|
||||||
|
|
||||||
func (any *intAny) ToBool() bool {
|
func (any *intAny) ToBool() bool {
|
||||||
return any.ToInt64() != 0
|
return any.ToInt64() != 0
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
package jsoniter
|
package jsoniter
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
type invalidAny struct {
|
type invalidAny struct {
|
||||||
baseAny
|
baseAny
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *invalidAny) LastError() error {
|
func (any *invalidAny) LastError() error {
|
||||||
return nil
|
return any.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (any *invalidAny) ValueType() ValueType {
|
||||||
|
return Invalid
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *invalidAny) ToBool() bool {
|
func (any *invalidAny) ToBool() bool {
|
||||||
@ -40,7 +47,11 @@ func (any *invalidAny) WriteTo(stream *Stream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (any *invalidAny) Get(path ...interface{}) Any {
|
func (any *invalidAny) Get(path ...interface{}) Any {
|
||||||
return any
|
if any.err == nil {
|
||||||
|
return &invalidAny{baseAny{}, fmt.Errorf("get %v from invalid", path)}
|
||||||
|
} else {
|
||||||
|
return &invalidAny{baseAny{}, fmt.Errorf("%v, get %v from invalid", any.err, path)}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (any *invalidAny) Parse() *Iterator {
|
func (any *invalidAny) Parse() *Iterator {
|
||||||
|
@ -8,6 +8,10 @@ func (any *nilAny) LastError() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (any *nilAny) ValueType() ValueType {
|
||||||
|
return Nil
|
||||||
|
}
|
||||||
|
|
||||||
func (any *nilAny) ToBool() bool {
|
func (any *nilAny) ToBool() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package jsoniter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type objectLazyAny struct {
|
type objectLazyAny struct {
|
||||||
@ -13,6 +14,10 @@ type objectLazyAny struct {
|
|||||||
remaining []byte
|
remaining []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (any *objectLazyAny) ValueType() ValueType {
|
||||||
|
return Object
|
||||||
|
}
|
||||||
|
|
||||||
func (any *objectLazyAny) Parse() *Iterator {
|
func (any *objectLazyAny) Parse() *Iterator {
|
||||||
iter := any.iter
|
iter := any.iter
|
||||||
if iter == nil {
|
if iter == nil {
|
||||||
@ -178,12 +183,20 @@ func (any *objectLazyAny) Get(path ...interface{}) Any {
|
|||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
return any
|
return any
|
||||||
}
|
}
|
||||||
if len(path) == 1 {
|
var element Any
|
||||||
key := path[0].(string)
|
key, ok := path[0].(string)
|
||||||
return any.fillCacheUntil(key)
|
if ok {
|
||||||
|
element = any.fillCacheUntil(key)
|
||||||
|
if element == nil {
|
||||||
|
element = &invalidAny{baseAny{}, fmt.Errorf("%v not found in %v", key, any.cache)}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
key := path[0].(string)
|
element = &invalidAny{baseAny{}, fmt.Errorf("%v not found in %v", key, any.cache)}
|
||||||
return any.fillCacheUntil(key).Get(path[1:]...)
|
}
|
||||||
|
if len(path) == 1 {
|
||||||
|
return element
|
||||||
|
} else {
|
||||||
|
return element.Get(path[1:]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,10 @@ type stringLazyAny struct{
|
|||||||
cache string
|
cache string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (any *stringLazyAny) ValueType() ValueType {
|
||||||
|
return String
|
||||||
|
}
|
||||||
|
|
||||||
func (any *stringLazyAny) Parse() *Iterator {
|
func (any *stringLazyAny) Parse() *Iterator {
|
||||||
iter := any.iter
|
iter := any.iter
|
||||||
if iter == nil {
|
if iter == nil {
|
||||||
|
@ -90,6 +90,16 @@ func Test_array_lazy_any_get(t *testing.T) {
|
|||||||
should.Equal("[1,[2,3],4]", any.ToString())
|
should.Equal("[1,[2,3],4]", any.ToString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_array_lazy_any_get_invalid(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
any, err := UnmarshalAnyFromString("[]")
|
||||||
|
should.Nil(err)
|
||||||
|
should.Equal(Invalid, any.Get(1,1).ValueType())
|
||||||
|
should.NotNil(any.Get(1,1).LastError())
|
||||||
|
should.Equal(Invalid, any.Get("1").ValueType())
|
||||||
|
should.NotNil(any.Get("1").LastError())
|
||||||
|
}
|
||||||
|
|
||||||
func Test_array_lazy_any_set(t *testing.T) {
|
func Test_array_lazy_any_set(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
any, err := UnmarshalAnyFromString("[1,[2,3],4]")
|
any, err := UnmarshalAnyFromString("[1,[2,3],4]")
|
||||||
|
@ -110,6 +110,13 @@ func Test_read_int64_as_any(t *testing.T) {
|
|||||||
should.True(any.ToBool())
|
should.True(any.ToBool())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_int_lazy_any_get(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
any, err := UnmarshalAnyFromString("1234")
|
||||||
|
should.Nil(err)
|
||||||
|
should.Equal(Invalid, any.Get(1, "2").ValueType())
|
||||||
|
}
|
||||||
|
|
||||||
func Test_wrap_int(t *testing.T) {
|
func Test_wrap_int(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
str, err := MarshalToString(WrapInt64(100))
|
str, err := MarshalToString(WrapInt64(100))
|
||||||
|
@ -147,6 +147,14 @@ func Test_object_lazy_any_get(t *testing.T) {
|
|||||||
should.Equal("d", any.Get("a", "b", "c").ToString())
|
should.Equal("d", any.Get("a", "b", "c").ToString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_object_lazy_any_get_invalid(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
any, err := UnmarshalAnyFromString(`{}`)
|
||||||
|
should.Nil(err)
|
||||||
|
should.Equal(Invalid, any.Get("a", "b", "c").ValueType())
|
||||||
|
should.Equal(Invalid, any.Get(1).ValueType())
|
||||||
|
}
|
||||||
|
|
||||||
func Test_object_lazy_any_set(t *testing.T) {
|
func Test_object_lazy_any_set(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
any, err := UnmarshalAnyFromString(`{"a":{"b":{"c":"d"}}}`)
|
any, err := UnmarshalAnyFromString(`{"a":{"b":{"c":"d"}}}`)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user