tagexpr

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jan 25, 2019 License: Apache-2.0 Imports: 10 Imported by: 0

README

go-tagexpr

An interesting go struct tag expression syntax for field validation, etc.

Status

In development

Example

type T struct {
	A int            `tagexpr:"$<0||$>=100"`
	B string         `tagexpr:"len($)>1 && regexp('^\\w*$')"`
	C bool           `tagexpr:"{expr1:(f.g)$>0 && $}{expr2:'C must be true when T.f.g>0'}"`
	d []string       `tagexpr:"{match:len($)>0 && $[0]=='D'} {msg:sprintf('Invalid d: %v',$)}"`
	e map[string]int `tagexpr:"len($)==$['len']"`
	f struct {
		g int `tagexpr:"$"`
	}
}
vm := New("tagexpr")
err := vm.WarmUp(new(T))
if err != nil {
	panic(err)
}
t := &T{
	A: 107,
	B: "abc",
	C: true,
	d: []string{"x", "y"},
	e: map[string]int{"len": 1},
	f: struct {
		g int `tagexpr:"$"`
	}{1},
}
tagExpr, err := vm.Run(t)
if err != nil {
	panic(err)
}
fmt.Println(tagExpr.Eval("A.$"))
fmt.Println(tagExpr.Eval("B.$"))
fmt.Println(tagExpr.Eval("C.expr1"))
fmt.Println(tagExpr.Eval("C.expr2"))
if !tagExpr.Eval("d.match").(bool) {
	fmt.Println(tagExpr.Eval("d.msg"))
}
fmt.Println(tagExpr.Eval("e.$"))
fmt.Println(tagExpr.Eval("f.g.$"))
// Output:
// true
// true
// true
// C must be true when T.f.g>0
// Invalid d: [x y]
// true
// 1

Syntax

Struct tag syntax spec:

type T struct {
    Field1 T1 `tagName:"expression"`
    Field2 T2 `tagName:"{exprName:expression} [{exprName2:expression2}]..."`
    ...
}

NOTE: The exprName under the same struct field cannot be the same!

Operator or Expression example Explain
true bool "true"
false bool "false"
1 float64 "1"
1.0 float64 "1.0"
'S' String "S"
+ 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 in the struct field X
(X)$[0] The 0th element of the struct field X(type: map, slice, array)
len((X)$) Built-in function len, the length of struct field X
len() Built-in function len, the length of the current struct field
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

Operator priority(high -> low):

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

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Expr

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

Expr expression

type ExprNode

type ExprNode interface {
	SetParent(ExprNode)
	Parent() ExprNode
	LeftOperand() ExprNode
	RightOperand() ExprNode
	SetLeftOperand(ExprNode)
	SetRightOperand(ExprNode)
	Run(string, *TagExpr) interface{}
}

ExprNode expression interface

type Field

type Field struct {
	reflect.StructField
	// contains filtered or unexported fields
}

Field tag expression set of struct field

type Struct

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

Struct tag expression set of struct

type TagExpr

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

TagExpr struct tag expression evaluator

func (*TagExpr) Eval

func (t *TagExpr) Eval(selector string) interface{}

Eval evaluate the value of the struct tag expression by the selector expression. format: fieldName, fieldName.exprName, fieldName1.fieldName2.exprName1

func (*TagExpr) Range

func (t *TagExpr) Range(fn func(selector string, eval func() interface{}))

Range loop through each tag expression

type VM

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

VM struct tag expression interpreter

func New

func New(tagName string) *VM

New creates a tag expression interpreter that uses @tagName as the tag name.

func (*VM) Run

func (vm *VM) Run(structPtr interface{}) (*TagExpr, error)

func (*VM) WarmUp

func (vm *VM) WarmUp(structOrStructPtr interface{}) error

Jump to

Keyboard shortcuts

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