Skip to content

Commit

Permalink
Add full form access to rule functions
Browse files Browse the repository at this point in the history
  • Loading branch information
System-Glitch committed Oct 21, 2019
1 parent 01bf6ba commit 4890adf
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 52 deletions.
58 changes: 56 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ Send request to the server using curl or postman: `curl GET "http://localhost:90
```go
func init() {
// simple example
govalidator.AddCustomRule("must_john", func(field string, rule string, message string, value interface{}) error {
govalidator.AddCustomRule("must_john", func(field string, rule string, message string, value interface{}, form map[string]interface{}) error {
val := value.(string)
if val != "john" || val != "John" {
return fmt.Errorf("The %s field must be John or john", field)
Expand All @@ -189,7 +189,7 @@ func init() {

// custom rules to take fixed length word.
// e.g: word:5 will throw error if the field does not contain exact 5 word
govalidator.AddCustomRule("word", func(field string, rule string, message string, value interface{}) error {
govalidator.AddCustomRule("word", func(field string, rule string, message string, value interface{}, form map[string]interface{}) error {
valSlice := strings.Fields(value.(string))
l, _ := strconv.Atoi(strings.TrimPrefix(rule, "word:")) //handle other error
if len(valSlice) != l {
Expand All @@ -202,6 +202,60 @@ func init() {
```
Note: Array, map, slice can be validated by adding custom rules.

You can use the `form` parameter to compare one field with another.
```go
govalidator.AddCustomRule("greater_than", (f string, rule string, message string, v interface{}, form map[string]interface{}) error {
if form == nil { // All comparison rules should check if the form is provided
panic(errors.New("No form provided for comparison rule"))
}

compareToKey := strings.TrimPrefix(rule, "greater_than:")
err := fmt.Errorf("The %s field must be greater than the %s field", f, compareToKey)
compareToField := form[compareToKey]

if compareToField == nil { // Field to compare to doesn't exist or is empty
return err
}

// Get the value of the field we want to compare to
var compareToValue int
rv := reflect.ValueOf(compareToField)
switch rv.Kind() {
case reflect.String:
v, atoiErr := strconv.Atoi(compareToField.(string))
if atoiErr != nil {
panic(errStringToInt)
}
compareToValue = v
case reflect.Int:
compareToValue = compareToField.(int)
//...
// Handle other types such as float
}

// Do the comparison
rv2 := reflect.ValueOf(v)
switch rv2.Kind() {
case reflect.Int:
if v.(int) <= compareToValue {
return err
}
case reflect.String:
vInt, atoiErr := strconv.Atoi(v.(string))
if atoiErr != nil {
panic(errStringToInt)
}
if vInt <= compareToValue {
return err
}
//...
// Handle other types
}

return nil
})
```

### Custom Message/ Localization
If you need to translate validation message you can pass messages as options.

Expand Down
2 changes: 1 addition & 1 deletion doc/CUSTOM_RULE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
func init() {
// custom rules to take fixed length word.
// e.g: max_word:5 will throw error if the field contains more than 5 words
govalidator.AddCustomRule("max_word", func(field string, rule string, message string, value interface{}) error {
govalidator.AddCustomRule("max_word", func(field string, rule string, message string, value interface{}, form map[string]interface{}) error {
valSlice := strings.Fields(value.(string))
l, _ := strconv.Atoi(strings.TrimPrefix(rule, "max_word:")) //handle other error
if len(valSlice) > l {
Expand Down

0 comments on commit 4890adf

Please sign in to comment.