github.com/bytedance/go-tagexpr@v2.7.5-0.20210114074101-de5b8743ad85+incompatible/spec_operator.go (about)

     1  // Copyright 2019 Bytedance Inc. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package tagexpr
    16  
    17  import (
    18  	"math"
    19  )
    20  
    21  // --------------------------- Operator ---------------------------
    22  
    23  type additionExprNode struct{ exprBackground }
    24  
    25  func newAdditionExprNode() ExprNode { return &additionExprNode{} }
    26  
    27  func (ae *additionExprNode) Run(currField string, tagExpr *TagExpr) interface{} {
    28  	// positive number or Addition
    29  	v0 := ae.leftOperand.Run(currField, tagExpr)
    30  	v1 := ae.rightOperand.Run(currField, tagExpr)
    31  	switch r := v0.(type) {
    32  	case float64:
    33  		var v float64
    34  		v, _ = v1.(float64)
    35  		r += v
    36  		return r
    37  	case string:
    38  		var v string
    39  		v, _ = v1.(string)
    40  		r += v
    41  		return r
    42  	default:
    43  		return v1
    44  	}
    45  }
    46  
    47  type multiplicationExprNode struct{ exprBackground }
    48  
    49  func newMultiplicationExprNode() ExprNode { return &multiplicationExprNode{} }
    50  
    51  func (ae *multiplicationExprNode) Run(currField string, tagExpr *TagExpr) interface{} {
    52  	v0, _ := ae.leftOperand.Run(currField, tagExpr).(float64)
    53  	v1, _ := ae.rightOperand.Run(currField, tagExpr).(float64)
    54  	return v0 * v1
    55  }
    56  
    57  type divisionExprNode struct{ exprBackground }
    58  
    59  func newDivisionExprNode() ExprNode { return &divisionExprNode{} }
    60  
    61  func (de *divisionExprNode) Run(currField string, tagExpr *TagExpr) interface{} {
    62  	v1, _ := de.rightOperand.Run(currField, tagExpr).(float64)
    63  	if v1 == 0 {
    64  		return math.NaN()
    65  	}
    66  	v0, _ := de.leftOperand.Run(currField, tagExpr).(float64)
    67  	return v0 / v1
    68  }
    69  
    70  type subtractionExprNode struct{ exprBackground }
    71  
    72  func newSubtractionExprNode() ExprNode { return &subtractionExprNode{} }
    73  
    74  func (de *subtractionExprNode) Run(currField string, tagExpr *TagExpr) interface{} {
    75  	v0, _ := de.leftOperand.Run(currField, tagExpr).(float64)
    76  	v1, _ := de.rightOperand.Run(currField, tagExpr).(float64)
    77  	return v0 - v1
    78  }
    79  
    80  type remainderExprNode struct{ exprBackground }
    81  
    82  func newRemainderExprNode() ExprNode { return &remainderExprNode{} }
    83  
    84  func (re *remainderExprNode) Run(currField string, tagExpr *TagExpr) interface{} {
    85  	v1, _ := re.rightOperand.Run(currField, tagExpr).(float64)
    86  	if v1 == 0 {
    87  		return math.NaN()
    88  	}
    89  	v0, _ := re.leftOperand.Run(currField, tagExpr).(float64)
    90  	return float64(int64(v0) % int64(v1))
    91  }
    92  
    93  type equalExprNode struct{ exprBackground }
    94  
    95  func newEqualExprNode() ExprNode { return &equalExprNode{} }
    96  
    97  func (ee *equalExprNode) Run(currField string, tagExpr *TagExpr) interface{} {
    98  	v0 := ee.leftOperand.Run(currField, tagExpr)
    99  	v1 := ee.rightOperand.Run(currField, tagExpr)
   100  	switch r := v0.(type) {
   101  	case float64:
   102  		r1, ok := v1.(float64)
   103  		if ok {
   104  			return r == r1
   105  		}
   106  	case string:
   107  		r1, ok := v1.(string)
   108  		if ok {
   109  			return r == r1
   110  		}
   111  	case bool:
   112  		r1, ok := v1.(bool)
   113  		if ok {
   114  			return r == r1
   115  		}
   116  	case nil:
   117  		return v1 == nil
   118  	}
   119  	return false
   120  }
   121  
   122  type notEqualExprNode struct{ equalExprNode }
   123  
   124  func newNotEqualExprNode() ExprNode { return &notEqualExprNode{} }
   125  
   126  func (ne *notEqualExprNode) Run(currField string, tagExpr *TagExpr) interface{} {
   127  	return !ne.equalExprNode.Run(currField, tagExpr).(bool)
   128  }
   129  
   130  type greaterExprNode struct{ exprBackground }
   131  
   132  func newGreaterExprNode() ExprNode { return &greaterExprNode{} }
   133  
   134  func (ge *greaterExprNode) Run(currField string, tagExpr *TagExpr) interface{} {
   135  	v0 := ge.leftOperand.Run(currField, tagExpr)
   136  	v1 := ge.rightOperand.Run(currField, tagExpr)
   137  	switch r := v0.(type) {
   138  	case float64:
   139  		r1, ok := v1.(float64)
   140  		if ok {
   141  			return r > r1
   142  		}
   143  	case string:
   144  		r1, ok := v1.(string)
   145  		if ok {
   146  			return r > r1
   147  		}
   148  	}
   149  	return false
   150  }
   151  
   152  type greaterEqualExprNode struct{ exprBackground }
   153  
   154  func newGreaterEqualExprNode() ExprNode { return &greaterEqualExprNode{} }
   155  
   156  func (ge *greaterEqualExprNode) Run(currField string, tagExpr *TagExpr) interface{} {
   157  	v0 := ge.leftOperand.Run(currField, tagExpr)
   158  	v1 := ge.rightOperand.Run(currField, tagExpr)
   159  	switch r := v0.(type) {
   160  	case float64:
   161  		r1, ok := v1.(float64)
   162  		if ok {
   163  			return r >= r1
   164  		}
   165  	case string:
   166  		r1, ok := v1.(string)
   167  		if ok {
   168  			return r >= r1
   169  		}
   170  	}
   171  	return false
   172  }
   173  
   174  type lessExprNode struct{ exprBackground }
   175  
   176  func newLessExprNode() ExprNode { return &lessExprNode{} }
   177  
   178  func (le *lessExprNode) Run(currField string, tagExpr *TagExpr) interface{} {
   179  	v0 := le.leftOperand.Run(currField, tagExpr)
   180  	v1 := le.rightOperand.Run(currField, tagExpr)
   181  	switch r := v0.(type) {
   182  	case float64:
   183  		r1, ok := v1.(float64)
   184  		if ok {
   185  			return r < r1
   186  		}
   187  	case string:
   188  		r1, ok := v1.(string)
   189  		if ok {
   190  			return r < r1
   191  		}
   192  	}
   193  	return false
   194  }
   195  
   196  type lessEqualExprNode struct{ exprBackground }
   197  
   198  func newLessEqualExprNode() ExprNode { return &lessEqualExprNode{} }
   199  
   200  func (le *lessEqualExprNode) Run(currField string, tagExpr *TagExpr) interface{} {
   201  	v0 := le.leftOperand.Run(currField, tagExpr)
   202  	v1 := le.rightOperand.Run(currField, tagExpr)
   203  	switch r := v0.(type) {
   204  	case float64:
   205  		r1, ok := v1.(float64)
   206  		if ok {
   207  			return r <= r1
   208  		}
   209  	case string:
   210  		r1, ok := v1.(string)
   211  		if ok {
   212  			return r <= r1
   213  		}
   214  	}
   215  	return false
   216  }
   217  
   218  type andExprNode struct{ exprBackground }
   219  
   220  func newAndExprNode() ExprNode { return &andExprNode{} }
   221  
   222  func (ae *andExprNode) Run(currField string, tagExpr *TagExpr) interface{} {
   223  	for _, e := range [2]ExprNode{ae.leftOperand, ae.rightOperand} {
   224  		if !FakeBool(e.Run(currField, tagExpr)) {
   225  			return false
   226  		}
   227  	}
   228  	return true
   229  }
   230  
   231  type orExprNode struct{ exprBackground }
   232  
   233  func newOrExprNode() ExprNode { return &orExprNode{} }
   234  
   235  func (oe *orExprNode) Run(currField string, tagExpr *TagExpr) interface{} {
   236  	for _, e := range [2]ExprNode{oe.leftOperand, oe.rightOperand} {
   237  		if FakeBool(e.Run(currField, tagExpr)) {
   238  			return true
   239  		}
   240  	}
   241  	return false
   242  }