-
Notifications
You must be signed in to change notification settings - Fork 28
Description
Lack of old StringToSliceHookFunc causes 2 unexpected behaviors.
- An error converting input "1,2,3" to []int{1, 2, 3}.
- An error occurred while converting the input "". I expected to get the result []int{}, but I got []int{0}.
The issue number 1 is directly related with changing reflect.Kind to reflect.Type and it was also mentioned in the following issue:
#69
The issue number 2 occurs because with the new approach, the data received from the StringToSliceHookFunc is not converted from the interface{}(string)"" to interface {}([]string)[], as it was in the legacy approach.
Is it an expected behavior for "" -> []int{0}?
This conversion takes place in the method:
Line 476 in 1a66224
func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error { |
and
#L523C1-L529C2
After this step, the data should have interface {}([]string)[] type to avoid the following “if” block in the method:
Line 1183 in 1a66224
func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error { |
And following line gives us a slice with len=1 and cap=1, which is incorrect because the default value of 0 is assigned to it later.
Line 1214 in 1a66224
return d.decodeSlice(name, []interface{}{data}, val) |
A possible solution is:
Store two versions of StringToSliceHookFunc in the mapstructure /decode_hooks.go
One is StringToSliceHookFunc, and the other is LegacyStringToSliceHookFunc. The legacy function is as follows:
https://github.com/mitchellh/mapstructure/blob/8508981c8b6c964e6986dd8aa85490e70ce3c2e2/decode_hooks.go#L104
Link to solution PR:
#99
This solution provides upstream compatibility for the dependent repository.
It's worth mentioning that the hook indirectly fixes this, but if the behavior is unexpected, it can be fixed in decodeSlice.