fix: handle invalid values in Decoder's decode method

This commit is contained in:
wwqgtxx 2024-12-16 09:26:11 +08:00
parent c786b72030
commit 3f6823ba49
2 changed files with 38 additions and 0 deletions

View File

@ -86,7 +86,27 @@ func (d *Decoder) Decode(src map[string]any, dst any) error {
return nil return nil
} }
// isNil returns true if the input is nil or a typed nil pointer.
func isNil(input any) bool {
if input == nil {
return true
}
val := reflect.ValueOf(input)
return val.Kind() == reflect.Pointer && val.IsNil()
}
func (d *Decoder) decode(name string, data any, val reflect.Value) error { func (d *Decoder) decode(name string, data any, val reflect.Value) error {
if isNil(data) {
// If the data is nil, then we don't set anything
// Maybe we should set to zero value?
return nil
}
if !reflect.ValueOf(data).IsValid() {
// If the input value is invalid, then we just set the value
// to be the zero value.
val.Set(reflect.Zero(val.Type()))
return nil
}
for { for {
kind := val.Kind() kind := val.Kind()
if kind == reflect.Pointer && val.IsNil() { if kind == reflect.Pointer && val.IsNil() {

View File

@ -267,3 +267,21 @@ func TestStructure_TextUnmarshaller(t *testing.T) {
err = decoder.Decode(rawMap, s) err = decoder.Decode(rawMap, s)
assert.NotNilf(t, err, "should throw error: %#v", s) assert.NotNilf(t, err, "should throw error: %#v", s)
} }
func TestStructure_Null(t *testing.T) {
rawMap := map[string]any{
"opt": map[string]any{
"bar": nil,
},
}
s := struct {
Opt struct {
Bar string `test:"bar,optional"`
} `test:"opt,optional"`
}{}
err := decoder.Decode(rawMap, &s)
assert.Nil(t, err)
assert.Equal(t, s.Opt.Bar, "")
}