# README
validator 
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
- Required go version ≥1.9
Example
package validator_test
import (
"fmt"
vd "github.com/bytedance/go-tagexpr/validator"
)
func Example() {
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: "[email protected]",
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(failPath, msg string) error {
return fmt.Errorf(`{"succ":false, "error":"validation failed: %s"}`, failPath)
})
type F struct {
f struct {
g int `vd:"$%3==0"`
}
}
f := &F{}
f.f.g = 10
fmt.Println(vd.Validate(f))
fmt.Println(vd.Validate(map[string]*F{"a": f}))
fmt.Println(vd.Validate(map[*F]int{f: 1}))
fmt.Println(vd.Validate([][1]*F{{f}}))
fmt.Println(vd.Validate((*F)(nil)))
fmt.Println(vd.Validate(map[string]*F{}))
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":"validation failed: f.g"}
// {"succ":false, "error":"validation failed: a/f.g"}
// {"succ":false, "error":"validation failed: {k}/f.g"}
// {"succ":false, "error":"validation failed: 0/0/f.g"}
// unsupport data: nil
// <nil>
// <nil>
}
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
*
/
%
+
-
<
<=
>
>=
==
!=
&&
||
# Functions
Default returns the default validator.
New creates a struct fields validator.
RegFunc registers validator function expression.
SetErrorFactory customizes the factory of validation error for the default validator.
Validate uses the default validator to validate whether the fields of value is valid.
# Constants
ErrMsgExprName the name of the expression used to specify the message returned when validation failed.
MatchExprName the name of the expression used for validation.