Skip to content

Commit

Permalink
Refactored typeCheck to accept parent, fixing array/slice failing req…
Browse files Browse the repository at this point in the history
…uired check with empty values
  • Loading branch information
LCartwright committed Feb 10, 2021
1 parent 7a23bdc commit df06edd
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 12 deletions.
27 changes: 16 additions & 11 deletions validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ func ValidateMap(s map[string]interface{}, m map[string]interface{}) (bool, erro
Offset: 0,
Index: []int{index},
Anonymous: false,
}, val, nil)
}, val, nil, val)
if err != nil {
errs = append(errs, err)
}
Expand Down Expand Up @@ -1001,7 +1001,7 @@ func ValidateStruct(s interface{}) (bool, error) {
errs = append(errs, err)
}
}
resultField, err2 := typeCheck(valueField, typeField, val, nil)
resultField, err2 := typeCheck(valueField, typeField, val, nil, val)
if err2 != nil {

// Replace structure name with JSON name if there is a tag on the variable
Expand Down Expand Up @@ -1297,7 +1297,7 @@ func checkRequired(v reflect.Value, t reflect.StructField, options tagOptionsMap
return true, nil
}

func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options tagOptionsMap) (isValid bool, resultErr error) {
func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options tagOptionsMap, p reflect.Value) (isValid bool, resultErr error) {
if !v.IsValid() {
return false, nil
}
Expand All @@ -1324,10 +1324,15 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options
}

if isEmptyValue(v) {
// an empty value is not validated, checks only required
isValid, resultErr = checkRequired(v, t, options)
for key := range options {
delete(options, key)
if p.Kind() == reflect.Slice || p.Kind() == reflect.Array && p.Len() > 0 {
// empty values are allowed for elements of arrays/slices, the parent has already been checked against the zero type
return true, nil
} else {
// an empty value is not validated, checks only required
isValid, resultErr = checkRequired(v, t, options)
for key := range options {
delete(options, key)
}
}
return isValid, resultErr
}
Expand Down Expand Up @@ -1503,7 +1508,7 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options
var resultItem bool
var err error
if v.MapIndex(k).Kind() != reflect.Struct {
resultItem, err = typeCheck(v.MapIndex(k), t, o, options)
resultItem, err = typeCheck(v.MapIndex(k), t, o, options, v)
if err != nil {
return false, err
}
Expand All @@ -1523,7 +1528,7 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options
var resultItem bool
var err error
if v.Index(i).Kind() != reflect.Struct {
resultItem, err = typeCheck(v.Index(i), t, o, options)
resultItem, err = typeCheck(v.Index(i), t, o, options, v)
if err != nil {
return false, err
}
Expand All @@ -1548,7 +1553,7 @@ func typeCheck(v reflect.Value, t reflect.StructField, o reflect.Value, options
if v.IsNil() {
return true, nil
}
return typeCheck(v.Elem(), t, o, options)
return typeCheck(v.Elem(), t, o, options, v)
case reflect.Struct:
return true, nil
default:
Expand All @@ -1563,7 +1568,7 @@ func stripParams(validatorString string) string {
// isEmptyValue checks whether value empty or not
func isEmptyValue(v reflect.Value) bool {
switch v.Kind() {
case reflect.String, reflect.Array:
case reflect.String:
return v.Len() == 0
case reflect.Map, reflect.Slice:
return v.Len() == 0 || v.IsNil()
Expand Down
11 changes: 10 additions & 1 deletion validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2965,6 +2965,7 @@ type testByteMap map[byte]byte
type testByteSlice []byte
type testStringStringMap map[string]string
type testStringIntMap map[string]int
type testIntArray [8]int

func TestRequired(t *testing.T) {

Expand Down Expand Up @@ -3024,6 +3025,14 @@ func TestRequired(t *testing.T) {
},
true,
},
{
struct {
TestIntArray testIntArray `valid:"required"`
}{
testIntArray{0, 1, 2, 3, 4, 5, 6, 7},
},
true,
},
{
struct {
TestByteArray testByteArray `valid:"required"`
Expand All @@ -3042,7 +3051,7 @@ func TestRequired(t *testing.T) {
struct {
TestByteArray testByteArray `valid:"required"`
}{
testByteArray{'1', '2', '3', '4', '5', '6', '7', 'A'},
testByteArray{0x00, '1', '2', '3', '4', '5', '6', '7'},
},
true,
},
Expand Down

0 comments on commit df06edd

Please sign in to comment.