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  }