validator

package
v1.2.4 Latest Latest
Warning

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

Go to latest
Published: Apr 18, 2019 License: Apache-2.0 Imports: 4 Imported by: 0

README

validator GoDoc

A powerful validator that supports struct tag expression.

Feature

  • Support for a variety of common operator
  • Support for accessing arrays, slices, members of the dictionary
  • Support access to any field in the current structure
  • Support access to nested fields, non-exported fields, etc.
  • Support registers validator function expression
  • Built-in len, sprintf, regexp, email, phone functions
  • Support simple mode, or specify error message mode
  • Use offset pointers to directly take values, better performance

Example

package validator_test

import (
	"fmt"

	"github.com/bytedance/go-tagexpr/validator"
)

func Example() {
	var vd = validator.New("vd")

	type InfoRequest struct {
		Name   string `vd:"($!='Alice'||(Age)$==18) && regexp('\\w')"`
		Age    int    `vd:"$>0"`
		Email  string `vd:"email($)"`
		Phone1 string `vd:"phone($)"`
		Phone2 string `vd:"phone($,'CN')"`
	}
	info := InfoRequest{
		Name:   "Alice",
		Age:    18,
		Email:  "henrylee2cn@gmail.com",
		Phone1: "+8618812345678",
		Phone2: "18812345678",
	}
	fmt.Println(vd.Validate(info) == nil)

	type A struct {
		A    int `vd:"$<0||$>=100"`
		Info interface{}
	}
	info.Email = "xxx"
	a := &A{A: 107, Info: info}
	fmt.Println(vd.Validate(a))

	type B struct {
		B string `vd:"len($)>1 && regexp('^\\w*$')"`
	}
	b := &B{"abc"}
	fmt.Println(vd.Validate(b) == nil)

	type C struct {
		C bool `vd:"{@:(S.A)$>0 && !$}{msg:'C must be false when S.A>0'}"`
		S *A
	}
	c := &C{C: true, S: a}
	fmt.Println(vd.Validate(c))

	type D struct {
		d []string `vd:"{@:len($)>0 && $[0]=='D'} {msg:sprintf('invalid d: %v',$)}"`
	}
	d := &D{d: []string{"x", "y"}}
	fmt.Println(vd.Validate(d))

	type E struct {
		e map[string]int `vd:"len($)==$['len']"`
	}
	e := &E{map[string]int{"len": 2}}
	fmt.Println(vd.Validate(e))

	// Customizes the factory of validation error.
	vd.SetErrorFactory(func(fieldSelector, msg string) error {
		return fmt.Errorf(`{"succ":false, "error":"invalid parameter: %s"}`, fieldSelector)
	})

	type F struct {
		f struct {
			g int `vd:"$%3==0"`
		}
	}
	f := &F{}
	f.f.g = 10
	fmt.Println(vd.Validate(f))
	f = nil
	fmt.Println(vd.Validate(f))

	// Output:
	// true
	// invalid parameter: Email
	// true
	// C must be false when S.A>0
	// invalid d: [x y]
	// invalid parameter: e
	// {"succ":false, "error":"invalid parameter: f.g"}
	// cannot run nil data
}

Syntax

Struct tag syntax spec:

type T struct {
	// Simple model
    Field1 T1 `tagName:"expression"`
	// Specify error message mode
    Field2 T2 `tagName:"{@:expression}{msg:expression2}"`
    ...
}
Operator or Operand Explain
true false boolean
0 0.0 float64 "0"
'' String
\\' Escape ' delims in string
\" Escape " delims in string
nil nil, undefined
! not, suitable for bool, string, float64, nil, $ and ()
+ Digital addition or string splicing
- Digital subtraction or negative
* Digital multiplication
/ Digital division
% division remainder, as: float64(int64(a)%int64(b))
== eq
!= ne
> gt
>= ge
< lt
<= le
&& Logic and
|| Logic or
() Expression group
(X)$ Struct field value named X
(X.Y)$ Struct field value named X.Y
$ Shorthand for (X)$, omit (X) to indicate current struct field value
(X)$['A'] Map value with key A or struct A sub-field in the struct field X
(X)$[0] The 0th element or sub-field of the struct field X(type: map, slice, array, struct)
len((X)$) Built-in function len, the length of struct field X
regexp('^\\w*$', (X)$) Regular match the struct field X, return boolean
regexp('^\\w*$') Regular match the current struct field, return boolean
sprintf('X value: %v', (X)$) fmt.Sprintf, format the value of struct field X
email((X)$) Regular match the struct field X, return true if it is email
phone((X)$,<'defaultRegion'>) Regular match the struct field X, return true if it is phone

Operator priority(high -> low):

  • () ! bool float64 string nil
  • * / %
  • + -
  • < <= > >=
  • == !=
  • &&
  • ||

Documentation

Overview

Package validator is a powerful validator that supports struct tag expression.

Copyright 2019 Bytedance Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Example
package main

import (
	"fmt"

	"github.com/bytedance/go-tagexpr/validator"
)

func main() {
	var vd = validator.New("vd")

	type InfoRequest struct {
		Name   string `vd:"($!='Alice'||(Age)$==18) && regexp('\\w')"`
		Age    int    `vd:"$>0"`
		Email  string `vd:"email($)"`
		Phone1 string `vd:"phone($)"`
		Phone2 string `vd:"phone($,'CN')"`
	}
	info := InfoRequest{
		Name:   "Alice",
		Age:    18,
		Email:  "henrylee2cn@gmail.com",
		Phone1: "+8618812345678",
		Phone2: "18812345678",
	}
	fmt.Println(vd.Validate(info) == nil)

	type A struct {
		A    int `vd:"$<0||$>=100"`
		Info interface{}
	}
	info.Email = "xxx"
	a := &A{A: 107, Info: info}
	fmt.Println(vd.Validate(a))

	type B struct {
		B string `vd:"len($)>1 && regexp('^\\w*$')"`
	}
	b := &B{"abc"}
	fmt.Println(vd.Validate(b) == nil)

	type C struct {
		C bool `vd:"{@:(S.A)$>0 && !$}{msg:'C must be false when S.A>0'}"`
		S *A
	}
	c := &C{C: true, S: a}
	fmt.Println(vd.Validate(c))

	type D struct {
		d []string `vd:"{@:len($)>0 && $[0]=='D'} {msg:sprintf('invalid d: %v',$)}"`
	}
	d := &D{d: []string{"x", "y"}}
	fmt.Println(vd.Validate(d))

	type E struct {
		e map[string]int `vd:"len($)==$['len']"`
	}
	e := &E{map[string]int{"len": 2}}
	fmt.Println(vd.Validate(e))

	// Customizes the factory of validation error.
	vd.SetErrorFactory(func(fieldSelector, msg string) error {
		return fmt.Errorf(`{"succ":false, "error":"invalid parameter: %s"}`, fieldSelector)
	})

	type F struct {
		f struct {
			g int `vd:"$%3==0"`
		}
	}
	f := &F{}
	f.f.g = 10
	fmt.Println(vd.Validate(f))
	f = nil
	fmt.Println(vd.Validate(f))

}
Output:

true
invalid parameter: Email
true
C must be false when S.A>0
invalid d: [x y]
invalid parameter: e
{"succ":false, "error":"invalid parameter: f.g"}
cannot run nil data

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func RegValidateFunc added in v1.2.0

func RegValidateFunc(funcName string, fn func(args ...interface{}) bool, force ...bool) error

RegValidateFunc registers validator function expression. NOTE:

example: phone($) or phone($,'CN');
If @force=true, allow to cover the existed same @funcName;
The go number types always are float64;
The go string types always are string.

Types

type Error added in v1.1.2

type Error struct {
	FieldSelector, Msg string
}

Error validate error

func (*Error) Error added in v1.1.2

func (e *Error) Error() string

Error implements error interface.

type Validator

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

Validator struct fields validator

func New

func New(tagName string) *Validator

New creates a struct fields validator.

func (*Validator) SetErrorFactory

func (v *Validator) SetErrorFactory(errFactory func(fieldSelector, msg string) error) *Validator

SetErrorFactory customizes the factory of validation error.

func (*Validator) Validate

func (v *Validator) Validate(structPtr interface{}) error

Validate validates whether the fields of structPtr is valid.

Jump to

Keyboard shortcuts

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