github.com/tencent/goom@v1.0.1/arg/expr.go (about) 1 package arg 2 3 import ( 4 "fmt" 5 "reflect" 6 ) 7 8 // Expr 表达式接口, 实现了 equals、any、in、field(x)等表达式匹配 9 // 一般类型参数默认使用 equals 表达式, 实现了 Expr 接口的参数表达式将使用对于的表达式进行匹配参数 10 type Expr interface { 11 // Eval 执行一个表达式, 12 // 一般地, 如果执行结果是 true, 则参数 Match 成功 13 // input 表达式执行时的入参 14 Eval(input []reflect.Value) (bool, error) 15 // Resolve 解析参数类型 16 Resolve(types []reflect.Type) error 17 } 18 19 // AnyExpr 和任意参数值比较 20 type AnyExpr struct { 21 } 22 23 // Resolve AnyExpr 表达式解析 24 func (a *AnyExpr) Resolve(_ []reflect.Type) error { 25 return nil 26 } 27 28 // Eval 执行 AnyExpr 表达式 29 func (a *AnyExpr) Eval(_ []reflect.Value) (bool, error) { 30 return true, nil 31 } 32 33 // EqualsExpr 表达式实现了两个参数是否相等的规则计算 34 type EqualsExpr struct { 35 arg interface{} 36 argV reflect.Value 37 } 38 39 // Resolve EqualsExpr 表达式解析 40 func (e *EqualsExpr) Resolve(types []reflect.Type) error { 41 // types 只会有一个元素 42 if len(types) != 1 { 43 return fmt.Errorf("EqualsExpr.Resolve status error") 44 } 45 e.argV = toValue(e.arg, types[0]) 46 return nil 47 } 48 49 // Eval 执行 EqualsExpr 表达式 50 func (e *EqualsExpr) Eval(input []reflect.Value) (bool, error) { 51 // input 只会有一个元素 52 if len(input) != 1 { 53 return false, fmt.Errorf("EqualsExpr.Resolve status error") 54 } 55 if equal(e.argV, input[0]) { 56 return true, nil 57 } 58 return false, nil 59 } 60 61 // InExpr 包含表达式执行 62 type InExpr struct { 63 args []interface{} 64 expressions [][]Expr 65 } 66 67 // Resolve InExpr 表达式解析 68 func (i *InExpr) Resolve(types []reflect.Type) error { 69 expressions := make([][]Expr, 0) 70 for _, v := range i.args { 71 param, ok := v.([]interface{}) 72 if !ok { 73 param = []interface{}{v} 74 } 75 76 expr, err := ToExpr(param, types) 77 if err != nil { 78 return err 79 } 80 expressions = append(expressions, expr) 81 } 82 i.expressions = expressions 83 return nil 84 } 85 86 // Eval InExpr 表达式执行 87 func (i *InExpr) Eval(input []reflect.Value) (bool, error) { 88 outer: 89 for _, one := range i.expressions { 90 if len(input) != len(one) { 91 return false, nil 92 } 93 for i, param := range one { 94 v, err := param.Eval([]reflect.Value{input[i]}) 95 if err != nil { 96 return false, err 97 } 98 if !v { 99 continue outer 100 } 101 } 102 103 return true, nil 104 } 105 return false, nil 106 }