mirror of
https://github.com/json-iterator/go.git
synced 2025-05-13 21:36:29 +02:00
Merge pull request #168 from olegshaldybin/null-booleans
Allow null booleans
This commit is contained in:
commit
f8eb43eda3
@ -331,7 +331,9 @@ type boolCodec struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
*((*bool)(ptr)) = iter.ReadBool()
|
if !iter.ReadNil() {
|
||||||
|
*((*bool)(ptr)) = iter.ReadBool()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
|
func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
@ -350,6 +352,10 @@ type emptyInterfaceCodec struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (codec *emptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
func (codec *emptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
|
if iter.ReadNil() {
|
||||||
|
*((*interface{})(ptr)) = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
existing := *((*interface{})(ptr))
|
existing := *((*interface{})(ptr))
|
||||||
if existing != nil && reflect.TypeOf(existing).Kind() == reflect.Ptr {
|
if existing != nil && reflect.TypeOf(existing).Kind() == reflect.Ptr {
|
||||||
iter.ReadVal(existing)
|
iter.ReadVal(existing)
|
||||||
|
@ -82,3 +82,32 @@ func Test_decode_string_bool(t *testing.T) {
|
|||||||
err = Unmarshal([]byte(`{"Field":true}`), &obj)
|
err = Unmarshal([]byte(`{"Field":true}`), &obj)
|
||||||
should.NotNil(err)
|
should.NotNil(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_bool_can_be_null(t *testing.T) {
|
||||||
|
type TestData struct {
|
||||||
|
Field bool `json:"field"`
|
||||||
|
}
|
||||||
|
should := require.New(t)
|
||||||
|
|
||||||
|
obj := TestData{}
|
||||||
|
data1 := []byte(`{"field": true}`)
|
||||||
|
err := Unmarshal(data1, &obj)
|
||||||
|
should.Equal(nil, err)
|
||||||
|
should.Equal(true, obj.Field)
|
||||||
|
|
||||||
|
data2 := []byte(`{"field": null}`)
|
||||||
|
err = Unmarshal(data2, &obj)
|
||||||
|
should.Equal(nil, err)
|
||||||
|
// Same behavior as stdlib, not touching the existing value.
|
||||||
|
should.Equal(true, obj.Field)
|
||||||
|
|
||||||
|
// Checking stdlib behavior as well
|
||||||
|
obj2 := TestData{}
|
||||||
|
err = json.Unmarshal(data1, &obj2)
|
||||||
|
should.Equal(nil, err)
|
||||||
|
should.Equal(true, obj2.Field)
|
||||||
|
|
||||||
|
err = json.Unmarshal(data2, &obj2)
|
||||||
|
should.Equal(nil, err)
|
||||||
|
should.Equal(true, obj2.Field)
|
||||||
|
}
|
||||||
|
@ -3,9 +3,10 @@ package jsoniter
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"testing"
|
"testing"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_write_array_of_interface(t *testing.T) {
|
func Test_write_array_of_interface(t *testing.T) {
|
||||||
@ -313,3 +314,40 @@ func Test_unmarshal_ptr_to_interface(t *testing.T) {
|
|||||||
should.Nil(err)
|
should.Nil(err)
|
||||||
should.Equal("&{value}", fmt.Sprintf("%v", obj))
|
should.Equal("&{value}", fmt.Sprintf("%v", obj))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_nil_out_null_interface(t *testing.T) {
|
||||||
|
type TestData struct {
|
||||||
|
Field interface{} `json:"field"`
|
||||||
|
}
|
||||||
|
should := require.New(t)
|
||||||
|
|
||||||
|
var boolVar bool
|
||||||
|
obj := TestData{
|
||||||
|
Field: &boolVar,
|
||||||
|
}
|
||||||
|
|
||||||
|
data1 := []byte(`{"field": true}`)
|
||||||
|
|
||||||
|
err := Unmarshal(data1, &obj)
|
||||||
|
should.Equal(nil, err)
|
||||||
|
should.Equal(true, *(obj.Field.(*bool)))
|
||||||
|
|
||||||
|
data2 := []byte(`{"field": null}`)
|
||||||
|
|
||||||
|
err = Unmarshal(data2, &obj)
|
||||||
|
should.Equal(nil, err)
|
||||||
|
should.Equal(nil, obj.Field)
|
||||||
|
|
||||||
|
// Checking stdlib behavior matches.
|
||||||
|
obj2 := TestData{
|
||||||
|
Field: &boolVar,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(data1, &obj2)
|
||||||
|
should.Equal(nil, err)
|
||||||
|
should.Equal(true, *(obj2.Field.(*bool)))
|
||||||
|
|
||||||
|
err = json.Unmarshal(data2, &obj2)
|
||||||
|
should.Equal(nil, err)
|
||||||
|
should.Equal(nil, obj2.Field)
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user