This commit is contained in:
John Guo
2022-05-26 15:28:17 +08:00
parent 39af6e51c4
commit 6abbc57c96
4 changed files with 40 additions and 11 deletions

View File

@ -101,10 +101,10 @@ func (v *Validator) doCheckMap(ctx context.Context, params interface{}) Error {
switch originTypeAndKind.OriginKind {
case reflect.Map, reflect.Struct, reflect.Slice, reflect.Array:
v.doCheckValueRecursively(ctx, doCheckValueRecursivelyInput{
Value: item,
Type: originTypeAndKind.InputType,
OriginKind: originTypeAndKind.OriginKind,
ErrorMaps: errorMaps,
Value: item,
Type: originTypeAndKind.InputType,
Kind: originTypeAndKind.OriginKind,
ErrorMaps: errorMaps,
})
}
// Bail feature.

View File

@ -250,11 +250,11 @@ func (v *Validator) doCheckStruct(ctx context.Context, object interface{}) Error
}
switch field.OriginalKind() {
case reflect.Map, reflect.Struct, reflect.Slice, reflect.Array:
// Recursively check attribute struct/[]string/map/[]map.
// Recursively check attribute slice/map.
_, value = gutil.MapPossibleItemByKey(inputParamMap, field.Name())
v.doCheckValueRecursively(ctx, doCheckValueRecursivelyInput{
Value: value,
OriginKind: field.OriginalKind(),
Kind: field.OriginalKind(),
Type: field.Type().Type,
ErrorMaps: errorMaps,
ResultSequenceRules: &resultSequenceRules,

View File

@ -540,13 +540,22 @@ func (v *Validator) doCheckSingleBuildInRules(ctx context.Context, in doCheckBui
type doCheckValueRecursivelyInput struct {
Value interface{} // Value to be validated.
Type reflect.Type // Struct/map/slice type which to be recursively validated.
OriginKind reflect.Kind // Struct/map/slice kind to be asserted in following switch case.
Kind reflect.Kind // Struct/map/slice kind to be asserted in following switch case.
ErrorMaps map[string]map[string]error // The validated failed error map.
ResultSequenceRules *[]fieldRule // The validated failed rule in sequence.
}
func (v *Validator) doCheckValueRecursively(ctx context.Context, in doCheckValueRecursivelyInput) {
switch in.OriginKind {
switch in.Kind {
case reflect.Ptr:
v.doCheckValueRecursively(ctx, doCheckValueRecursivelyInput{
Value: in.Value,
Type: in.Type.Elem(),
Kind: in.Type.Elem().Kind(),
ErrorMaps: in.ErrorMaps,
ResultSequenceRules: in.ResultSequenceRules,
})
case reflect.Struct:
// Ignore data, rules and messages from parent.
validator := v.Clone()
@ -572,7 +581,7 @@ func (v *Validator) doCheckValueRecursively(ctx context.Context, in doCheckValue
v.doCheckValueRecursively(ctx, doCheckValueRecursivelyInput{
Value: item,
Type: mapTypeElem,
OriginKind: mapTypeKind,
Kind: mapTypeKind,
ErrorMaps: in.ErrorMaps,
ResultSequenceRules: in.ResultSequenceRules,
})
@ -596,7 +605,7 @@ func (v *Validator) doCheckValueRecursively(ctx context.Context, in doCheckValue
v.doCheckValueRecursively(ctx, doCheckValueRecursivelyInput{
Value: item,
Type: in.Type.Elem(),
OriginKind: in.Type.Elem().Kind(),
Kind: in.Type.Elem().Kind(),
ErrorMaps: in.ErrorMaps,
ResultSequenceRules: in.ResultSequenceRules,
})

View File

@ -10,7 +10,6 @@ import (
"testing"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/test/gtest"
)
@ -274,6 +273,27 @@ func Test_CheckStruct_Recursively_SliceAttribute(t *testing.T) {
err := g.Validator().Assoc(data).Data(teacher).Run(ctx)
t.Assert(err, `Student Name is required`)
})
// https://github.com/gogf/gf/issues/1864
gtest.C(t, func(t *gtest.T) {
type Student struct {
Name string `v:"required"`
Age int
}
type Teacher struct {
Name string
Students []*Student
}
var (
teacher = Teacher{}
data = g.Map{
"name": "john",
"students": `[{"age":2},{"name":"jack", "age":4}]`,
}
)
err := g.Validator().Assoc(data).Data(teacher).Run(ctx)
t.Assert(err, `The Name field is required`)
})
}
func Test_CheckStruct_Recursively_SliceAttribute_WithTypeAlias(t *testing.T) {