@@ -9,6 +9,7 @@ package gvalid
9
9
import (
10
10
"github.com/gogf/gf/internal/structs"
11
11
"github.com/gogf/gf/util/gconv"
12
+ "reflect"
12
13
"strings"
13
14
)
14
15
@@ -17,13 +18,31 @@ var (
17
18
aliasNameTagPriority = []string {"param" , "params" , "p" } // aliasNameTagPriority specifies the alias tag priority array.
18
19
)
19
20
20
- // CheckStruct validates strcut and returns the error result.
21
+ // CheckStruct validates struct and returns the error result.
21
22
//
22
23
// The parameter <object> should be type of struct/*struct.
23
24
// The parameter <rules> can be type of []string/map[string]string. It supports sequence in error result
24
25
// if <rules> is type of []string.
25
26
// The optional parameter <messages> specifies the custom error messages for specified keys and rules.
26
27
func (v * Validator ) CheckStruct (object interface {}, rules interface {}, messages ... CustomMsg ) * Error {
28
+ var (
29
+ errorMaps = make (ErrorMap ) // Returned error.
30
+ )
31
+ mapField , err := structs .FieldMap (object , aliasNameTagPriority )
32
+ if err != nil {
33
+ return newErrorStr ("invalid_object" , err .Error ())
34
+ }
35
+ // It checks the struct recursively the its attribute is also a struct.
36
+ for _ , field := range mapField {
37
+ if field .OriginalKind () == reflect .Struct {
38
+ if err := v .CheckStruct (field .Value , rules , messages ... ); err != nil {
39
+ // It merges the errors into single error map.
40
+ for k , m := range err .errors {
41
+ errorMaps [k ] = m
42
+ }
43
+ }
44
+ }
45
+ }
27
46
// It here must use structs.TagFields not structs.FieldMap to ensure error sequence.
28
47
tagField , err := structs .TagFields (object , structTagPriority )
29
48
if err != nil {
@@ -39,7 +58,6 @@ func (v *Validator) CheckStruct(object interface{}, rules interface{}, messages
39
58
customMessage = make (CustomMsg )
40
59
fieldAliases = make (map [string ]string ) // Alias names for <messages> overwriting struct tag names.
41
60
errorRules = make ([]string , 0 ) // Sequence rules.
42
- errorMaps = make (ErrorMap ) // Returned error
43
61
)
44
62
switch v := rules .(type ) {
45
63
// Sequence tag: []sequence tag
@@ -85,10 +103,6 @@ func (v *Validator) CheckStruct(object interface{}, rules interface{}, messages
85
103
return nil
86
104
}
87
105
// Checks and extends the parameters map with struct alias tag.
88
- mapField , err := structs .FieldMap (object , aliasNameTagPriority )
89
- if err != nil {
90
- return newErrorStr ("invalid_object" , err .Error ())
91
- }
92
106
for nameOrTag , field := range mapField {
93
107
params [nameOrTag ] = field .Value .Interface ()
94
108
params [field .Name ()] = field .Value .Interface ()
@@ -167,10 +181,10 @@ func (v *Validator) CheckStruct(object interface{}, rules interface{}, messages
167
181
// It checks each rule and its value in loop.
168
182
if e := v .doCheck (key , value , rule , customMessage [key ], params ); e != nil {
169
183
_ , item := e .FirstItem ()
170
- // ===========================================================
171
- // Only in map and struct validations, if value is nil or empty
172
- // string and has no required* rules, it clears the error message.
173
- // ===========================================================
184
+ // ===================================================================
185
+ // Only in map and struct validations, if value is nil or empty string
186
+ // and has no required* rules, it clears the error message.
187
+ // ===================================================================
174
188
if value == nil || gconv .String (value ) == "" {
175
189
required := false
176
190
// rule => error
0 commit comments