gvalid

package
v2.0.0-rc2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 24, 2022 License: MIT Imports: 26 Imported by: 52

Documentation

Overview

Package gvalid implements powerful and useful data/form validation functionality.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func DeleteRule

func DeleteRule(rules ...string)

DeleteRule deletes custom defined validation one or more rules and associated functions from global package.

func GetRegisteredRuleMap

func GetRegisteredRuleMap() map[string]RuleFunc

GetRegisteredRuleMap returns all the custom registered rules and associated functions.

func RegisterRule

func RegisterRule(rule string, f RuleFunc)

RegisterRule registers custom validation rule and function for package.

func RegisterRuleByMap

func RegisterRuleByMap(m map[string]RuleFunc)

RegisterRuleByMap registers custom validation rules using map for package.

Types

type CustomMsg

type CustomMsg = map[string]interface{}

CustomMsg is the custom error message type, like: map[field] => string|map[rule]string

type Error

type Error interface {
	Code() gcode.Code
	Current() error
	Error() string
	FirstItem() (key string, messages map[string]error)
	FirstRule() (rule string, err error)
	FirstError() (err error)
	Items() (items []map[string]map[string]error)
	Map() map[string]error
	Maps() map[string]map[string]error
	String() string
	Strings() (errs []string)
}

Error is the validation error for validation result.

type RuleFunc

type RuleFunc func(ctx context.Context, in RuleFuncInput) error

RuleFunc is the custom function for data validation.

type RuleFuncInput

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
}

RuleFuncInput holds the input parameters that passed to custom rule function RuleFunc.

type Validator

type Validator struct {
	// contains filtered or unexported fields
}

Validator is the validation manager for chaining operations.

func New

func New() *Validator

New creates and returns a new Validator.

Example
package main

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/util/gvalid"
)

func main() {
	validator := gvalid.New()
	if err := validator.Data(16).Rules("min:18").Run(context.Background()); err != nil {
		fmt.Println(err)
	}

}
Output:

The value `16` must be equal or greater than 18

func (*Validator) Assoc

func (v *Validator) Assoc(assoc interface{}) *Validator

Assoc is a chaining operation function, which sets associated validation data for current operation. The optional parameter `assoc` is usually type of map, which specifies the parameter map used in union validation. Calling this function with `assoc` also sets `useDataInsteadOfObjectAttributes` true

Example
package main

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
)

func main() {
	type User struct {
		Name string `v:"required"`
		Type int    `v:"required"`
	}
	data := g.Map{
		"name": "john",
	}
	user := User{}

	if err := gconv.Scan(data, &user); err != nil {
		panic(err)
	}

	if err := g.Validator().Data(user).Assoc(data).Run(context.Background()); err != nil {
		fmt.Print(err)
	}

}
Output:

The Type field is required

func (*Validator) Bail

func (v *Validator) Bail() *Validator

Bail sets the mark for stopping validation after the first validation error.

Example
package main

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Account   string `v:"required|length:6,16|same:QQ"`
		QQ        string
		Password  string `v:"required|same:Password2"`
		Password2 string `v:"required"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Account:   "gf",
			QQ:        "123456",
			Password:  "goframe.org",
			Password2: "goframe.org",
		}
	)

	if err := g.Validator().Bail().Data(req).Run(ctx); err != nil {
		fmt.Println("Use Bail Error:", err)
	}

	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println("Not Use Bail Error:", err)
	}

}
Output:

Use Bail Error: The Account value `gf` length must be between 6 and 16
Not Use Bail Error: The Account value `gf` length must be between 6 and 16; The Account value `gf` must be the same as field QQ

func (*Validator) Ci

func (v *Validator) Ci() *Validator

Ci sets the mark for Case-Insensitive for those rules that need value comparison.

Example
package main

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Account   string `v:"required"`
		Password  string `v:"required|same:Password2"`
		Password2 string `v:"required"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Account:   "gf",
			Password:  "Goframe.org", // Diff from Password2, but because of "ci", rule check passed
			Password2: "goframe.org",
		}
	)

	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println("Not Use CI Error:", err)
	}

	if err := g.Validator().Ci().Data(req).Run(ctx); err == nil {
		fmt.Println("Use CI Passed!")
	}

}
Output:

Not Use CI Error: The Password value `Goframe.org` must be the same as field Password2
Use CI Passed!

func (*Validator) Clone

func (v *Validator) Clone() *Validator

Clone creates and returns a new Validator which is a shallow copy of current one.

Example
package main

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	if err := g.Validator().Data(16).Rules("min:18").Run(context.Background()); err != nil {
		fmt.Println(err)
	}

	if err := g.Validator().Clone().Data(20).Run(context.Background()); err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("Check Success!")
	}

}
Output:

The value `16` must be equal or greater than 18
Check Success!

func (*Validator) Data

func (v *Validator) Data(data interface{}) *Validator

Data is a chaining operation function, which sets validation data for current operation.

Example
package main

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Password1 string `v:"password"`
		Password2 string `v:"password"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Password1: "goframe",
			Password2: "gofra", // error length between 6 and 18
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The Password2 value `gofra` is not a valid password format

func (*Validator) I18n

func (v *Validator) I18n(i18nManager *gi18n.Manager) *Validator

I18n sets the i18n manager for the validator.

Example
package main

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/i18n/gi18n"
	"github.com/gogf/gf/v2/util/gvalid"
)

func main() {
	var (
		i18nManager = gi18n.New()
		ctxCn       = gi18n.WithLanguage(context.Background(), "cn")
		validator   = gvalid.New()
	)

	validator = validator.Data(16).Rules("min:18")

	if err := validator.Run(context.Background()); err != nil {
		fmt.Println(err)
	}

	if err := validator.I18n(i18nManager).Run(ctxCn); err != nil {
		fmt.Println(err)
	}

}
Output:

The value `16` must be equal or greater than 18
字段值`16`字段最小值应当为18

func (*Validator) Messages

func (v *Validator) Messages(messages interface{}) *Validator

Messages is a chaining operation function, which sets custom error messages for current operation. The parameter `messages` can be type of string/[]string/map[string]string. It supports sequence in error result if `rules` is type of []string.

Example
package main

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	if err := g.Validator().Data(16).Rules("min:18").Messages("Can not regist, Age is less then 18!").Run(context.Background()); err != nil {
		fmt.Println(err)
	}

}
Output:

Can not regist, Age is less then 18!

func (*Validator) RuleFunc

func (v *Validator) RuleFunc(rule string, f RuleFunc) *Validator

RuleFunc registers one custom rule function to current Validator.

Example
package main

import (
	"context"
	"errors"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gvalid"
)

func main() {
	var (
		ctx             = context.Background()
		lenErrRuleName  = "LenErr"
		passErrRuleName = "PassErr"
		lenErrRuleFunc  = func(ctx context.Context, in gvalid.RuleFuncInput) error {
			pass := in.Value.String()
			if len(pass) != 6 {
				return errors.New(in.Message)
			}
			return nil
		}
		passErrRuleFunc = func(ctx context.Context, in gvalid.RuleFuncInput) error {
			pass := in.Value.String()
			if m := in.Data.Map(); m["data"] != pass {
				return errors.New(in.Message)
			}
			return nil
		}
	)

	type LenErrStruct struct {
		Value string `v:"uid@LenErr#Value Length Error!"`
		Data  string `p:"data"`
	}

	st := &LenErrStruct{
		Value: "123",
		Data:  "123456",
	}
	// single error sample
	if err := g.Validator().RuleFunc(lenErrRuleName, lenErrRuleFunc).Data(st).Run(ctx); err != nil {
		fmt.Println(err)
	}

	type MultiErrorStruct struct {
		Value string `v:"uid@LenErr|PassErr#Value Length Error!|Pass is not Same!"`
		Data  string `p:"data"`
	}

	multi := &MultiErrorStruct{
		Value: "123",
		Data:  "123456",
	}
	// multi error sample
	if err := g.Validator().RuleFunc(lenErrRuleName, lenErrRuleFunc).RuleFunc(passErrRuleName, passErrRuleFunc).Data(multi).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

Value Length Error!
Value Length Error!; Pass is not Same!

func (*Validator) RuleFuncMap

func (v *Validator) RuleFuncMap(m map[string]RuleFunc) *Validator

RuleFuncMap registers multiple custom rule functions to current Validator.

Example
package main

import (
	"context"
	"errors"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gvalid"
)

func main() {
	var (
		ctx             = context.Background()
		lenErrRuleName  = "LenErr"
		passErrRuleName = "PassErr"
		lenErrRuleFunc  = func(ctx context.Context, in gvalid.RuleFuncInput) error {
			pass := in.Value.String()
			if len(pass) != 6 {
				return errors.New(in.Message)
			}
			return nil
		}
		passErrRuleFunc = func(ctx context.Context, in gvalid.RuleFuncInput) error {
			pass := in.Value.String()
			if m := in.Data.Map(); m["data"] != pass {
				return errors.New(in.Message)
			}
			return nil
		}
		ruleMap = map[string]gvalid.RuleFunc{
			lenErrRuleName:  lenErrRuleFunc,
			passErrRuleName: passErrRuleFunc,
		}
	)

	type MultiErrorStruct struct {
		Value string `v:"uid@LenErr|PassErr#Value Length Error!|Pass is not Same!"`
		Data  string `p:"data"`
	}

	multi := &MultiErrorStruct{
		Value: "123",
		Data:  "123456",
	}

	if err := g.Validator().RuleFuncMap(ruleMap).Data(multi).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

Value Length Error!; Pass is not Same!

func (*Validator) Rules

func (v *Validator) Rules(rules interface{}) *Validator

Rules is a chaining operation function, which sets custom validation rules for current operation.

Example
package main

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	if err := g.Validator().Data(16).Rules("min:18").Run(context.Background()); err != nil {
		fmt.Println(err)
	}

}
Output:

The value `16` must be equal or greater than 18

func (*Validator) Run

func (v *Validator) Run(ctx context.Context) Error

Run starts validating the given data with rules and messages.

Example
package main

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	// check value mode
	if err := g.Validator().Data(16).Rules("min:18").Run(context.Background()); err != nil {
		fmt.Println("check value err:", err)
	}
	// check map mode
	data := map[string]interface{}{
		"passport":  "",
		"password":  "123456",
		"password2": "1234567",
	}
	rules := map[string]string{
		"passport":  "required|length:6,16",
		"password":  "required|length:6,16|same:password2",
		"password2": "required|length:6,16",
	}
	if err := g.Validator().Data(data).Rules(rules).Run(context.Background()); err != nil {
		fmt.Println("check map err:", err)
	}
	// check struct mode
	type Params struct {
		Page      int    `v:"required|min:1"`
		Size      int    `v:"required|between:1,100"`
		ProjectId string `v:"between:1,10000"`
	}
	rules = map[string]string{
		"Page":      "required|min:1",
		"Size":      "required|between:1,100",
		"ProjectId": "between:1,10000",
	}
	obj := &Params{
		Page: 0,
		Size: 101,
	}
	if err := g.Validator().Data(obj).Run(context.Background()); err != nil {
		fmt.Println("check struct err:", err)
	}

	// May Output:
	// check value err: The value `16` must be equal or greater than 18
	// check map err: The passport field is required; The passport value `` length must be between 6 and 16; The password value `123456` must be the same as field password2
	// check struct err: The Page value `0` must be equal or greater than 1; The Size value `101` must be between 1 and 100
}
Output:

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL