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