mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
improve RuleFunc for package gvalid
This commit is contained in:
@ -6,16 +6,29 @@
|
||||
|
||||
package gvalid
|
||||
|
||||
import "context"
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/container/gvar"
|
||||
)
|
||||
|
||||
// RuleFunc is the custom function for data validation.
|
||||
//
|
||||
// The parameter `rule` specifies the validation rule string, like "required", "between:1,100", etc.
|
||||
// The parameter `value` specifies the value for this rule to validate.
|
||||
// The parameter `message` specifies the custom error message or configured i18n message for this rule.
|
||||
// The parameter `data` specifies the `data` which is passed to the Validator. It might be a type of map/struct or a nil value.
|
||||
// You can ignore the parameter `data` if you do not really need it in your custom validation rule.
|
||||
type RuleFunc func(ctx context.Context, rule string, value interface{}, message string, data interface{}) error
|
||||
type RuleFunc func(ctx context.Context, in RuleFuncInput) error
|
||||
|
||||
// RuleFuncInput holds the input parameters that passed to custom rule function RuleFunc.
|
||||
type RuleFuncInput struct {
|
||||
// Rule specifies the validation rule string, like "required", "between:1,100", etc.
|
||||
Rule string
|
||||
|
||||
// Message specifies the custom error message or configured i18n message for this rule.
|
||||
Message string
|
||||
|
||||
// Value specifies the value for this rule to validate.
|
||||
Value *gvar.Var
|
||||
|
||||
// Data specifies the `data` which is passed to the Validator. It might be a type of map/struct or a nil value.
|
||||
// You can ignore the parameter `Data` if you do not really need it in your custom validation rule.
|
||||
Data *gvar.Var
|
||||
}
|
||||
|
||||
var (
|
||||
// customRuleFuncMap stores the custom rule functions.
|
||||
@ -24,13 +37,22 @@ var (
|
||||
)
|
||||
|
||||
// RegisterRule registers custom validation rule and function for package.
|
||||
// It returns error if there's already the same rule registered previously.
|
||||
func RegisterRule(rule string, f RuleFunc) error {
|
||||
customRuleFuncMap[rule] = f
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteRule deletes custom defined validation rule and its function from global package.
|
||||
func DeleteRule(rule string) {
|
||||
delete(customRuleFuncMap, rule)
|
||||
// RegisterRuleByMap registers custom validation rules using map for package.
|
||||
func RegisterRuleByMap(m map[string]RuleFunc) error {
|
||||
for k, v := range m {
|
||||
customRuleFuncMap[k] = v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteRule deletes custom defined validation one or more rules and associated functions from global package.
|
||||
func DeleteRule(rules ...string) {
|
||||
for _, rule := range rules {
|
||||
delete(customRuleFuncMap, rule)
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ package gvalid
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/container/gvar"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
@ -133,7 +134,12 @@ func (v *Validator) doCheckValue(ctx context.Context, input doCheckValueInput) E
|
||||
if customRuleFunc != nil {
|
||||
// It checks custom validation rules with most priority.
|
||||
message := v.getErrorMessageByRule(ctx, ruleKey, customMsgMap)
|
||||
if err := customRuleFunc(ctx, ruleItems[index], input.Value, message, input.DataRaw); err != nil {
|
||||
if err := customRuleFunc(ctx, RuleFuncInput{
|
||||
Rule: ruleItems[index],
|
||||
Message: message,
|
||||
Value: gvar.New(input.Value),
|
||||
Data: gvar.New(input.DataRaw),
|
||||
}); err != nil {
|
||||
match = false
|
||||
errorMsgArray[ruleKey] = err.Error()
|
||||
} else {
|
||||
|
||||
@ -127,17 +127,17 @@ func ExampleRegisterRule() {
|
||||
}
|
||||
|
||||
rule := "unique-name"
|
||||
gvalid.RegisterRule(rule, func(ctx context.Context, rule string, value interface{}, message string, data interface{}) error {
|
||||
gvalid.RegisterRule(rule, func(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
var (
|
||||
id = data.(*User).Id
|
||||
name = gconv.String(value)
|
||||
id = in.Data.Val().(*User).Id
|
||||
name = gconv.String(in.Value)
|
||||
)
|
||||
n, err := g.Model("user").Where("id != ? and name = ?", id, name).Count()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n > 0 {
|
||||
return errors.New(message)
|
||||
return errors.New(in.Message)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@ -149,8 +149,8 @@ func ExampleRegisterRule() {
|
||||
|
||||
func ExampleRegisterRule_OverwriteRequired() {
|
||||
rule := "required"
|
||||
gvalid.RegisterRule(rule, func(ctx context.Context, rule string, value interface{}, message string, data interface{}) error {
|
||||
reflectValue := reflect.ValueOf(value)
|
||||
gvalid.RegisterRule(rule, func(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
reflectValue := reflect.ValueOf(in.Value.Val())
|
||||
if reflectValue.Kind() == reflect.Ptr {
|
||||
reflectValue = reflectValue.Elem()
|
||||
}
|
||||
@ -171,7 +171,7 @@ func ExampleRegisterRule_OverwriteRequired() {
|
||||
isEmpty = reflectValue.Len() == 0
|
||||
}
|
||||
if isEmpty {
|
||||
return errors.New(message)
|
||||
return errors.New(in.Message)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -12,8 +12,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
"github.com/gogf/gf/v2/util/gvalid"
|
||||
)
|
||||
@ -22,14 +20,14 @@ func Test_CustomRule1(t *testing.T) {
|
||||
rule := "custom"
|
||||
err := gvalid.RegisterRule(
|
||||
rule,
|
||||
func(ctx context.Context, rule string, value interface{}, message string, data interface{}) error {
|
||||
pass := gconv.String(value)
|
||||
func(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
pass := in.Value.String()
|
||||
if len(pass) != 6 {
|
||||
return errors.New(message)
|
||||
return errors.New(in.Message)
|
||||
}
|
||||
m := gconv.Map(data)
|
||||
m := in.Data.Map()
|
||||
if m["data"] != pass {
|
||||
return errors.New(message)
|
||||
return errors.New(in.Message)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
@ -71,10 +69,10 @@ func Test_CustomRule1(t *testing.T) {
|
||||
|
||||
func Test_CustomRule2(t *testing.T) {
|
||||
rule := "required-map"
|
||||
err := gvalid.RegisterRule(rule, func(ctx context.Context, rule string, value interface{}, message string, data interface{}) error {
|
||||
m := gconv.Map(value)
|
||||
err := gvalid.RegisterRule(rule, func(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
m := in.Value.Map()
|
||||
if len(m) == 0 {
|
||||
return errors.New(message)
|
||||
return errors.New(in.Message)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@ -115,12 +113,12 @@ func Test_CustomRule2(t *testing.T) {
|
||||
|
||||
func Test_CustomRule_AllowEmpty(t *testing.T) {
|
||||
rule := "allow-empty-str"
|
||||
err := gvalid.RegisterRule(rule, func(ctx context.Context, rule string, value interface{}, message string, data interface{}) error {
|
||||
s := gconv.String(value)
|
||||
err := gvalid.RegisterRule(rule, func(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
s := in.Value.String()
|
||||
if len(s) == 0 || s == "gf" {
|
||||
return nil
|
||||
}
|
||||
return errors.New(message)
|
||||
return errors.New(in.Message)
|
||||
})
|
||||
gtest.Assert(err, nil)
|
||||
// Check.
|
||||
@ -160,13 +158,13 @@ func Test_CustomRule_AllowEmpty(t *testing.T) {
|
||||
|
||||
func TestValidator_RuleFunc(t *testing.T) {
|
||||
ruleName := "custom_1"
|
||||
ruleFunc := func(ctx context.Context, rule string, value interface{}, message string, data interface{}) error {
|
||||
pass := gconv.String(value)
|
||||
ruleFunc := func(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
pass := in.Value.String()
|
||||
if len(pass) != 6 {
|
||||
return errors.New(message)
|
||||
return errors.New(in.Message)
|
||||
}
|
||||
if m := gconv.Map(data); m["data"] != pass {
|
||||
return errors.New(message)
|
||||
if m := in.Data.Map(); m["data"] != pass {
|
||||
return errors.New(in.Message)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -214,13 +212,13 @@ func TestValidator_RuleFunc(t *testing.T) {
|
||||
|
||||
func TestValidator_RuleFuncMap(t *testing.T) {
|
||||
ruleName := "custom_1"
|
||||
ruleFunc := func(ctx context.Context, rule string, value interface{}, message string, data interface{}) error {
|
||||
pass := gconv.String(value)
|
||||
ruleFunc := func(ctx context.Context, in gvalid.RuleFuncInput) error {
|
||||
pass := in.Value.String()
|
||||
if len(pass) != 6 {
|
||||
return errors.New(message)
|
||||
return errors.New(in.Message)
|
||||
}
|
||||
if m := gconv.Map(data); m["data"] != pass {
|
||||
return errors.New(message)
|
||||
if m := in.Data.Map(); m["data"] != pass {
|
||||
return errors.New(in.Message)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user