vrule

package module
v1.0.4 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2024 License: MIT Imports: 16 Imported by: 0

README

基本介绍

vrule它具有以下功能:

  1. 使用gogf的校验规则
  2. 使用验证标记或自定义验证程序进行跨字段验证。
  3. 切片、数组和map,允许验证多维字段的任何或所有级别。
  4. 能够深入map的value和slice类型结构体以进行验证
  5. 提取自定义字段名称,例如,可以指定在验证时提取 JSON 名称,并在生成的 FieldError 中提供该名称
  6. 指定过滤掉某些字段
  7. 动态替换错误提示信息
  8. 可自定义的i18n错误消息。
  9. 可以将需要验证的结构体信息进行缓存,加快验证效率

安装

go版本要求 >=1.18
使用go get
go get -u github.com/wln32/vrule

然后将验证程序包导入到您自己的代码中

import github.com/wln32/vrule

校验规则文档

校验规则详细信息


基本使用

vrule使用v或者valid来标记字段是否需要被校验
使用GetFieldError来获取对应字段的错误提示信息

简单示例
type Basic struct {
    Int8Ptr  *int8          `v:"required"`
    String   string         `v:"required"`
    Int      int            `valid:"required"`

}
obj:=Basic{}
err := Struct(obj).(*ValidationError)
fmt.Println(err.GetFieldError("Int8Ptr"))
fmt.Println(err.GetFieldError("String"))
fmt.Println(err.GetFieldError("Int"))

required-without关联规则示例

格式: required-without:field1,field2,...
必需参数(当所给定任意字段值其中之一为空时)。当前字段必须有值

type Foo struct {
    Bar *Bar `p:"bar" v:"required-without:Baz"`
    Baz *Baz `p:"baz" v:"required-without:Bar"`
}
type Bar struct {
    BarKey string `p:"bar_key" v:"required"`
}
type Baz struct {
    BazKey string `p:"baz_key" v:"required"`
}
err := Struct(foo)


注册自定义规则的验证

type CustomStruct struct {
	Name string `v:"trim-length:6"`
}
fn := func(ctx context.Context, in *ruleimpl.CustomRuleInput) error {
    val := in.Value.(string)
    trimVal := strings.TrimSpace(val)
    trimLength, err := strconv.Atoi(in.Args)
    if err != nil {
        return err
    }

    if len(trimVal) != trimLength {
        return fmt.Errorf("the length of the string after removing spaces must be %d characters", trimLength)
    }
    return nil
}
// 注册自定义规则验证
err := RegisterCustomRuleFunc(RegisterCustomRuleOption{
    RuleName: "trim-length",
    Fn:       fn,
})


过滤掉某些字段

一般情况下我们需要过滤掉一些字段,可以使用SetFilterFieldFunc这个函数来实现
返回true代表需要被过滤
返回false代表需要被验证

valid := New()

valid.SetFilterFieldFunc(func(structType reflect.Type, field reflect.StructField) bool {
	// 如果字段带有d tag的我们就过滤掉,不验证这个字段
	tag := field.Tag.Get("d")
	if tag != "" {
		return true
	}
	return false
})

只获取第一个错误

vrule默认获取到全部的错误,不会在第一个错误时停下
如果需要第一个错误就返回需要调用StopOnFirstError

valid := New()
// 设置为true代表遇到第一个错误时就立即返回
valid.StopOnFirstError(true)

替换错误提示信息

required = The {field} field is required
这是vrule的required规则错误提示模板
如果发生错误,vrule会将{field}替换为检验的字段名

例如以下

type Basic struct {
	String  string    `json:"string" v:"required"`		
}

如果需要将{field}替换为别的内容,可以使用SetFieldNameFunc提取自定义的字段名

valid := New()
valid.SetFieldNameFunc(func(structType reflect.Type, field reflect.StructField) string {
    // 使用字段的json tag作为错误提示时的字段名{field}
	name := field.Tag.Get("json")
    if name == "" {
        name = field.Name
    }
    return name
})

发生错误时,vrule会返回The String field is required这样的错误信息
除此之外,vrule还会替换以下的模板字段

  • {value} 字段的实际值,替换发生在运行时
  • {max} max和between规则下替换,是一个静态的数字类型的值
  • {min} min和between规则下替换,是一个静态的数字类型的值
  • {pattern} 是一个正则表达式
  • {size} size规则下,是一个静态的数字类型的值
  • {field1} 依赖于某些字段的名字
  • {value1} 依赖于某些字段的实际值
  • {format} 格式化规则

错误提示信息

GetFieldError 基础类型,或者只要map或者slice的元素是基本类型就可以,例如map[k]int,[]int
GetStructFieldError 如果字段是struct类型
GetMapFieldError 如果map的v是struct类型,例如map[k]struct或者map[k]*struct
GetSliceFieldError 如果切片的元素是struct类型,例如[]struct,[]*struct

简单示例
type Test struct {
    Pass1 string `v:"required|same:Pass2"`
    Pass2 string `v:"required|same:Pass1"`
	BasicSlice []int   `v:"required"`
}
type Example struct {
    Id   int
    Name string `v:"required"`
    Pass Test
}
obj := &Example{
    Name: "",
    Pass: Test{
        Pass1: "1",
        Pass2: "2",
    },
}
err := Struct(obj).(*ValidationError)
// 可以获取到Name字段的错误
err.GetFieldError("Name")
// 
err.GetFieldError("BasicSlice")
// 可以获取到Pass结构体字段下的Pass1错误
err.GetStructFieldError("Pass").GetFieldError("Pass1")
// 可以获取到Pass结构体字段下的Pass2错误
err.GetStructFieldError("Pass").GetFieldError("Pass2")

复杂示例
type Pass struct {
    Pass1 string `v:"required|same:Pass2"`
    Pass2 string `v:"required|same:Pass1"`
}
type User struct {
    Id     int
    Name   string `v:"required"`
    Passes []Pass
}
obj := &User{
    Name: "",
    Passes: []Pass{
        {
            Pass1: "1",
            Pass2: "2",
        },
        {
            Pass1: "3",
            Pass2: "4",
        },
    },
}
// 获取name字段的错误
err.GetFieldError("Name")
// 获取Passes切片字段的第一个的结构体的错误
index1 := err.GetSliceFieldError("Passes").GetError(0)
// 获取Passes切片字段的第二个的结构体的错误
index2 := err.GetSliceFieldError("Passes").GetError(1)
// 分别获取对应索引的结构体下字段的错误信息
index1.GetFieldError("Pass1")
index1.GetFieldError("Pass2")
// 分别获取对应索引的结构体下字段的错误信息
index2.GetFieldError("Pass1")
index2.GetFieldError("Pass2")


i18n

type Test struct {
    Args  string `v:"required" `
    Args2 int64  `v:"between:2,15" `
    Args3 int    `v:"max:60" `
}
valid := New()
valid.I18nSetLanguage("zh-CN")
obj := &TestI18nStruct{
    Args:  "",
    Args2: 60,
    Args3: 61,
}
err := valid.Struct(obj).(*ValidationError)
err.GetFieldError("Args") // Args字段不能为空
err.GetFieldError("Args2")// "Args2字段值`60`必须介于 2和15之间
err.GetFieldError("Args3")// Args3字段值`61`字段最大值应当为60

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RegisterCustomRuleFunc

func RegisterCustomRuleFunc(option RegisterCustomRuleOption) error

func RegisterCustomRuleFuncWithParse

func RegisterCustomRuleFuncWithParse(ruleName string, fn func(structRule StructRule, fieldRule FieldRules, args []string) ruleimpl.ValidFunc) error

让用户自定义规则的解析函数

func Struct

func Struct(a any) error

func StructCtx

func StructCtx(ctx context.Context, a any) error

func StructNotCache

func StructNotCache(a any) error

Types

type BasicFieldError

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

func (BasicFieldError) DetailError

func (e BasicFieldError) DetailError() string

func (BasicFieldError) Error

func (e BasicFieldError) Error() string

func (BasicFieldError) Errors

func (e BasicFieldError) Errors() []error

func (BasicFieldError) GetRuleError

func (e BasicFieldError) GetRuleError(rule string) error

type DetailError

type DetailError interface {
	DetailError() string
}

type ErrorHandler added in v1.0.3

type ErrorHandler interface {
	ErrorHandler(v, v1 any) error
}

type Errors

type Errors []error

func (Errors) Error

func (e Errors) Error() string

func (Errors) GetErrorWithIndex

func (e Errors) GetErrorWithIndex(i int) error

type FieldKind

type FieldKind int
const (
	BasicFiled FieldKind = iota + 1
	// []struct []*struct
	SliceFiled
	// map[k]struct map[k]*struct
	MapField
	StructrField
	// time gtime
	TimeField
)

type FieldRules

type FieldRules struct {
	// v:"[LongName@]RuleArray[#msg]"
	Name string

	// 按 | 解析的rule和msg
	// rule=>[value1,value2]   example: length:6,16 => length=>{6,16}
	RuleArray map[string][]string
	// rule=> msg
	MsgArray map[string]string

	// 字段类型
	Type reflect.Type

	FieldName string
	// 字段在结构体中的索引,反射的时候直接根据索引获取
	FieldIndex int

	// fields 如果kind 是struct才有效,其他的无效
	StructRule *StructRule

	// 指针类型 requiredPtr
	// slice map array  requiredLen
	// func(ctx context.Context,in fieldValidFuncInput)
	Funcs map[string]ruleimpl.ValidFunc
	// contains filtered or unexported fields
}

func (*FieldRules) CheckStructField

func (f *FieldRules) CheckStructField(ctx context.Context, fieldVal reflect.Value,
	structPtr reflect.Value, verr *ValidationError, validOption ValidRuleOption) bool

fieldVal 字段的值 structPtr 结构体指针 verr 错误 validOption 校验选项 返回一个bool值,表示是否继续下个字段的校验 field: basic | struct | slice | map

func (*FieldRules) FieldType

func (f *FieldRules) FieldType() reflect.Type

type MapFieldError

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

func (MapFieldError) DetailError

func (e MapFieldError) DetailError() string

func (MapFieldError) Error

func (e MapFieldError) Error() string

func (MapFieldError) Errors

func (e MapFieldError) Errors() []error

func (MapFieldError) GetError

func (e MapFieldError) GetError(key string) ValidationError

type ParseRuleOption

type ParseRuleOption struct {
	// 过滤字段
	FilterFieldFunc func(structType reflect.Type, field reflect.StructField) bool
	FieldNameFunc   func(structType reflect.Type, field reflect.StructField) string
}

type RegisterCustomRuleOption

type RegisterCustomRuleOption struct {
	// 规则名称
	RuleName string
	// 自定义规则的验证函数
	Fn ruleimpl.CustomValidRuleFunc
}

校验时rule

type SliceFieldError

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

func (SliceFieldError) DetailError

func (e SliceFieldError) DetailError() string

func (SliceFieldError) Error

func (e SliceFieldError) Error() string

func (SliceFieldError) Errors

func (e SliceFieldError) Errors() []error

func (SliceFieldError) GetError

func (e SliceFieldError) GetError(index int) ValidationError

type StructCache

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

func (*StructCache) AddStructRule

func (s *StructCache) AddStructRule(v *StructRule)

func (*StructCache) GetStructRule

func (s *StructCache) GetStructRule(typ reflect.Type) *StructRule

func (*StructCache) GetStructRuleOrCreate

func (s *StructCache) GetStructRuleOrCreate(typ reflect.Type, v *Validator) *StructRule

type StructRule

type StructRule struct {
	RuleFields []*FieldRules
	// LongName = pkgpath + structName
	LongName string
	// ShortName = structName
	ShortName string
	Type      reflect.Type
}

func ParseStruct

func ParseStruct(a any) *StructRule

func (*StructRule) CheckStruct

func (s *StructRule) CheckStruct(ctx context.Context, structPtr reflect.Value,
	verr *ValidationError, validOption ValidRuleOption,
)

struct: field*

func (*StructRule) Valid

func (s *StructRule) Valid(ctx context.Context, val reflect.Value, validOption ValidRuleOption) error

type TranslationOption

type TranslationOption struct {
	TranslateFunc func(ctx context.Context, content string) string
}

type ValidRuleOption

type ValidRuleOption struct {
	// 遇到第一个错误时是否停止
	StopOnFirstError bool
}

type ValidationError

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

func NewValidationError

func NewValidationError(structName string) *ValidationError

func (*ValidationError) AddFieldError

func (v *ValidationError) AddFieldError(name string, fieldErr error)

func (*ValidationError) DetailError

func (v *ValidationError) DetailError() string

func (*ValidationError) Error

func (v *ValidationError) Error() string

func (*ValidationError) Errors

func (v *ValidationError) Errors() Errors

func (ValidationError) GetFieldError

func (v ValidationError) GetFieldError(name string) BasicFieldError

func (ValidationError) GetMapFieldError

func (v ValidationError) GetMapFieldError(name string) MapFieldError

func (ValidationError) GetSliceFieldError

func (v ValidationError) GetSliceFieldError(name string) SliceFieldError

func (ValidationError) GetStructFieldError

func (v ValidationError) GetStructFieldError(name string) *ValidationError

type Validator

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

func New

func New() *Validator

func (*Validator) I18nSetLanguage

func (v *Validator) I18nSetLanguage(language string) *Validator

func (*Validator) I18nSetPath

func (v *Validator) I18nSetPath(path string) *Validator

func (*Validator) ParseStruct

func (v *Validator) ParseStruct(a any, cache *StructCache) *StructRule

func (*Validator) SetFieldNameFunc

func (v *Validator) SetFieldNameFunc(f func(structType reflect.Type, field reflect.StructField) string)

func (*Validator) SetFilterFieldFunc

func (v *Validator) SetFilterFieldFunc(f func(structType reflect.Type, field reflect.StructField) bool)

过滤那些字段,主要是带有v规则的字段

func (*Validator) SetI18n added in v1.0.3

func (v *Validator) SetI18n(path string, language string)

func (*Validator) StopOnFirstError

func (v *Validator) StopOnFirstError(b bool)

func (*Validator) Struct

func (v *Validator) Struct(a any) error

func (*Validator) StructCtx

func (v *Validator) StructCtx(ctx context.Context, a any) error

func (*Validator) StructNotCache

func (v *Validator) StructNotCache(a any) error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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