Skip to content
This repository was archived by the owner on Dec 15, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion extra/fuzzy_decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strings"
"unsafe"

"github.com/json-iterator/go"
jsoniter "github.com/json-iterator/go"
"github.com/modern-go/reflect2"
)

Expand Down Expand Up @@ -143,6 +143,7 @@ func RegisterFuzzyDecoders() {
*((*uint64)(ptr)) = iter.ReadUint64()
}
}})
jsoniter.RegisterTypeDecoder("bool", &fuzzyBoolDecoder{})
}

type tolerateEmptyArrayExtension struct {
Expand Down Expand Up @@ -292,3 +293,43 @@ func (decoder *fuzzyFloat64Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.It
iter.ReportError("fuzzyFloat64Decoder", "not number or string")
}
}

type fuzzyBoolDecoder struct {
}

func (decoder *fuzzyBoolDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
valueType := iter.WhatIsNext()
switch valueType {
case jsoniter.NumberValue:
*((*bool)(ptr)) = iter.ReadFloat64() != 0
case jsoniter.StringValue:
str := iter.ReadString()
switch str {
case "", "0":
*((*bool)(ptr)) = false
default:
*((*bool)(ptr)) = true
}
case jsoniter.BoolValue:
*((*bool)(ptr)) = iter.ReadBool()
// In order to stay consistent with the other decoders here, leaving arrays and objects out for now.
// case jsoniter.ObjectValue:
// iter.Skip()
// *((*bool)(ptr)) = true
// case jsoniter.ArrayValue:
// var nonEmptyArray bool
// iter.ReadArrayCB(
// func(*jsoniter.Iterator) bool {
// iter.Skip()
// nonEmptyArray = true
// return true
// },
// )
// *((*bool)(ptr)) = nonEmptyArray
case jsoniter.NilValue:
iter.Skip()
*((*bool)(ptr)) = false
default:
iter.ReportError("fuzzyBoolDecoder", "not number, string or bool")
}
}
61 changes: 60 additions & 1 deletion extra/fuzzy_decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package extra
import (
"testing"

"github.com/json-iterator/go"
jsoniter "github.com/json-iterator/go"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -325,6 +325,57 @@ func Test_any_to_float64(t *testing.T) {
should.NotNil(jsoniter.UnmarshalFromString("[]", &val))
}

func Test_any_to_bool(t *testing.T) {
should := require.New(t)
var val bool

// number to bool
should.Nil(jsoniter.UnmarshalFromString(`10`, &val))
should.Equal(true, val)
should.Nil(jsoniter.UnmarshalFromString(`10.1`, &val))
should.Equal(true, val)
should.Nil(jsoniter.UnmarshalFromString(`0`, &val))
should.Equal(false, val)
should.Nil(jsoniter.UnmarshalFromString(`0.0`, &val))
should.Equal(false, val)
should.Nil(jsoniter.UnmarshalFromString(`-10`, &val))
should.Equal(true, val)
should.Nil(jsoniter.UnmarshalFromString(`-10.1`, &val))
should.Equal(true, val)

// string to bool
should.Nil(jsoniter.UnmarshalFromString(`""`, &val))
should.Equal(false, val)
should.Nil(jsoniter.UnmarshalFromString(`"0"`, &val))
should.Equal(false, val)
should.Nil(jsoniter.UnmarshalFromString(`"false"`, &val))
should.Equal(true, val)
should.Nil(jsoniter.UnmarshalFromString(`"string"`, &val))
should.Equal(true, val)

// bool to bool
should.Nil(jsoniter.UnmarshalFromString(`false`, &val))
should.Equal(false, val)
should.Nil(jsoniter.UnmarshalFromString(`true`, &val))
should.Equal(true, val)

// object to bool
// TODO, according to other decoders' tests
// should.Nil(jsoniter.UnmarshalFromString(`{}`, &val))
// should.Equal(true, val)
// should.Nil(jsoniter.UnmarshalFromString(`{"key":"value"}`, &val))
// should.Equal(true, val)
should.NotNil(jsoniter.UnmarshalFromString(`{}`, &val))

// array to bool
// TODO, according to other decoders' tests
// should.Nil(jsoniter.UnmarshalFromString(`[]`, &val))
// should.Equal(false, val)
// should.Nil(jsoniter.UnmarshalFromString(`["item"]`, &val))
// should.Equal(true, val)
should.NotNil(jsoniter.UnmarshalFromString(`[]`, &val))
}

func Test_empty_array_as_map(t *testing.T) {
should := require.New(t)
var val map[string]interface{}
Expand Down Expand Up @@ -391,3 +442,11 @@ func Test_null_to_float64(t *testing.T) {
err := jsoniter.Unmarshal(body, &message)
should.NoError(err)
}

func Test_null_to_bool(t *testing.T) {
should := require.New(t)
body := []byte(`null`)
var message bool
err := jsoniter.Unmarshal(body, &message)
should.NoError(err)
}