1
0
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:
Tao Wen 2017-09-14 20:58:31 -05:00 committed by GitHub
commit f8eb43eda3
3 changed files with 75 additions and 2 deletions

View File

@ -331,7 +331,9 @@ type boolCodec struct {
}
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) {
@ -350,6 +352,10 @@ type emptyInterfaceCodec struct {
}
func (codec *emptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if iter.ReadNil() {
*((*interface{})(ptr)) = nil
return
}
existing := *((*interface{})(ptr))
if existing != nil && reflect.TypeOf(existing).Kind() == reflect.Ptr {
iter.ReadVal(existing)

View File

@ -82,3 +82,32 @@ func Test_decode_string_bool(t *testing.T) {
err = Unmarshal([]byte(`{"Field":true}`), &obj)
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)
}

View File

@ -3,9 +3,10 @@ package jsoniter
import (
"encoding/json"
"fmt"
"github.com/stretchr/testify/require"
"testing"
"unsafe"
"github.com/stretchr/testify/require"
)
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.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)
}