commit
						1e1068e81c
					
				| @ -334,3 +334,41 @@ func (v *Validation) Valid(obj interface{}) (b bool, err error) { | ||||
| 
 | ||||
| 	return !v.HasErrors(), nil | ||||
| } | ||||
| 
 | ||||
| // Recursively validate a struct. | ||||
| // Step1: Validate by v.Valid | ||||
| // Step2: If pass on step1, then reflect obj's fields | ||||
| // Step3: Do the Recursively validation to all struct or struct pointer fields | ||||
| func (v *Validation) RecursiveValid(objc interface{}) (bool, error) { | ||||
| 	//Step 1: validate obj itself firstly | ||||
| 	// fails if objc is not struct | ||||
| 	pass, err := v.Valid(objc) | ||||
| 	if err != nil || false == pass { | ||||
| 		return pass, err // Stop recursive validation | ||||
| 	} else { //pass | ||||
| 		// Step 2: Validate struct's struct fields | ||||
| 		objT := reflect.TypeOf(objc) | ||||
| 		objV := reflect.ValueOf(objc) | ||||
| 
 | ||||
| 		if isStructPtr(objT) { | ||||
| 			objT = objT.Elem() | ||||
| 			objV = objV.Elem() | ||||
| 		} | ||||
| 
 | ||||
| 		for i := 0; i < objT.NumField(); i++ { | ||||
| 
 | ||||
| 			t := objT.Field(i).Type | ||||
| 
 | ||||
| 			// Recursive applies to struct or pointer to structs fields | ||||
| 			if isStruct(t) || isStructPtr(t) { | ||||
| 				// Step 3: do the recursive validation | ||||
| 				// Only valid the Public field recursively | ||||
| 				if objV.Field(i).CanInterface() { | ||||
| 					pass, err = v.RecursiveValid(objV.Field(i).Interface()) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return pass, err | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -349,3 +349,33 @@ func TestValid(t *testing.T) { | ||||
| 		t.Errorf("Message key should be `Name.Match` but got %s", valid.Errors[0].Key) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestRecursiveValid(t *testing.T) { | ||||
| 	type User struct { | ||||
| 		Id   int | ||||
| 		Name string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"` | ||||
| 		Age  int    `valid:"Required;Range(1, 140)"` | ||||
| 	} | ||||
| 
 | ||||
| 	type AnonymouseUser struct { | ||||
| 		Id2   int | ||||
| 		Name2 string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"` | ||||
| 		Age2  int    `valid:"Required;Range(1, 140)"` | ||||
| 	} | ||||
| 
 | ||||
| 	type Account struct { | ||||
| 		Password string `valid:"Required"` | ||||
| 		U        User | ||||
| 		AnonymouseUser | ||||
| 	} | ||||
| 	valid := Validation{} | ||||
| 
 | ||||
| 	u := Account{Password: "abc123_", U: User{}} | ||||
| 	b, err := valid.RecursiveValid(u) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if b { | ||||
| 		t.Error("validation should not be passed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user