diff --git a/validator_instance.go b/validator_instance.go index 973964fc..7c378fb7 100644 --- a/validator_instance.go +++ b/validator_instance.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "reflect" + "strconv" "strings" "sync" "time" @@ -157,6 +158,14 @@ func (v Validate) ValidateMapCtx(ctx context.Context, data map[string]interface{ if len(err) > 0 { errs[field] = err } + } else if reflect.ValueOf(rule).Kind() == reflect.Map && reflect.ValueOf(data[field]).Kind() == reflect.Slice { + for i := 0; i < reflect.ValueOf(data[field]).Len(); i++ { + fieldWithIndex := field + "[" + strconv.FormatInt(int64(i), 10) + "]" + err := v.ValidateMapCtx(ctx, reflect.ValueOf(data[field]).Index(i).Interface().(map[string]interface{}), rule.(map[string]interface{})) + if len(err) > 0 { + errs[fieldWithIndex] = err + } + } } else if reflect.ValueOf(rule).Kind() == reflect.Map { errs[field] = errors.New("The field: '" + field + "' is not a map to dive") } else { diff --git a/validator_test.go b/validator_test.go index f6942037..92de2bb1 100644 --- a/validator_test.go +++ b/validator_test.go @@ -11418,3 +11418,50 @@ func TestPostCodeByIso3166Alpha2Field_InvalidKind(t *testing.T) { _ = New().Struct(test{"ABC", 123, false}) t.Errorf("Didn't panic as expected") } + +func TestValidate_ValidateMap_WithSlicesOfStructs(t *testing.T) { + test := map[string]interface{}{ + "value": []map[string]interface{}{ + { + "subValue": "abc", + }, {}, + }, + } + rules := map[string]interface{}{ + "value": map[string]interface{}{ + "subValue": "required", + }, + } + errs := New().ValidateMap(test, rules) + NotEqual(t, nil, errs) +} + +func TestValidate_ValidateMap_WithSubMaps(t *testing.T) { + test := map[string]interface{}{ + "value": map[string]interface{}{ + "subValue": "abc", + }, + } + rules := map[string]interface{}{ + "value": map[string]interface{}{ + "subValue": "required", + }, + } + errs := New().ValidateMap(test, rules) + NotEqual(t, nil, errs) +} + +func TestValidate_ValidateMap_InvalidType(t *testing.T) { + test := map[string]interface{}{ + "value": "abc", + } + rules := map[string]interface{}{ + "value": map[string]interface{}{ + "subValue": "required", + }, + } + errs := New().ValidateMap(test, rules) + if IsEqual(errs, nil) { + t.Fatal("expected field error") + } +}