github.com/bytedance/go-tagexpr/v2@v2.9.8/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  	"context"
    19  	"math"
    20  )
    21  
    22  // --------------------------- Operator ---------------------------
    23  
    24  type additionExprNode struct{ exprBackground }
    25  
    26  func (ae *additionExprNode) String() string {
    27  	return "+"
    28  }
    29  
    30  func newAdditionExprNode() ExprNode { return &additionExprNode{} }
    31  
    32  func (ae *additionExprNode) Run(ctx context.Context, currField string, tagExpr *TagExpr) interface{} {
    33  	// positive number or Addition
    34  	v0 := ae.leftOperand.Run(ctx, currField, tagExpr)
    35  	v1 := ae.rightOperand.Run(ctx, currField, tagExpr)
    36  	if s0, ok := toFloat64(v0, false); ok {
    37  		s1, _ := toFloat64(v1, true)
    38  		return s0 + s1
    39  	}
    40  	if s0, ok := toString(v0, false); ok {
    41  		s1, _ := toString(v1, true)
    42  		return s0 + s1
    43  	}
    44  	return v0
    45  }
    46  
    47  type multiplicationExprNode struct{ exprBackground }
    48  
    49  func (ae *multiplicationExprNode) String() string {
    50  	return "*"
    51  }
    52  
    53  func newMultiplicationExprNode() ExprNode { return &multiplicationExprNode{} }
    54  
    55  func (ae *multiplicationExprNode) Run(ctx context.Context, currField string, tagExpr *TagExpr) interface{} {
    56  	v0, _ := toFloat64(ae.leftOperand.Run(ctx, currField, tagExpr), true)
    57  	v1, _ := toFloat64(ae.rightOperand.Run(ctx, currField, tagExpr), true)
    58  	return v0 * v1
    59  }
    60  
    61  type divisionExprNode struct{ exprBackground }
    62  
    63  func (de *divisionExprNode) String() string {
    64  	return "/"
    65  }
    66  
    67  func newDivisionExprNode() ExprNode { return &divisionExprNode{} }
    68  
    69  func (de *divisionExprNode) Run(ctx context.Context, currField string, tagExpr *TagExpr) interface{} {
    70  	v1, _ := toFloat64(de.rightOperand.Run(ctx, currField, tagExpr), true)
    71  	if v1 == 0 {
    72  		return math.NaN()
    73  	}
    74  	v0, _ := toFloat64(de.leftOperand.Run(ctx, currField, tagExpr), true)
    75  	return v0 / v1
    76  }
    77  
    78  type subtractionExprNode struct{ exprBackground }
    79  
    80  func (de *subtractionExprNode) String() string {
    81  	return "-"
    82  }
    83  
    84  func newSubtractionExprNode() ExprNode { return &subtractionExprNode{} }
    85  
    86  func (de *subtractionExprNode) Run(ctx context.Context, currField string, tagExpr *TagExpr) interface{} {
    87  	v0, _ := toFloat64(de.leftOperand.Run(ctx, currField, tagExpr), true)
    88  	v1, _ := toFloat64(de.rightOperand.Run(ctx, currField, tagExpr), true)
    89  	return v0 - v1
    90  }
    91  
    92  type remainderExprNode struct{ exprBackground }
    93  
    94  func (re *remainderExprNode) String() string {
    95  	return "%"
    96  }
    97  
    98  func newRemainderExprNode() ExprNode { return &remainderExprNode{} }
    99  
   100  func (re *remainderExprNode) Run(ctx context.Context, currField string, tagExpr *TagExpr) interface{} {
   101  	v1, _ := toFloat64(re.rightOperand.Run(ctx, currField, tagExpr), true)
   102  	if v1 == 0 {
   103  		return math.NaN()
   104  	}
   105  	v0, _ := toFloat64(re.leftOperand.Run(ctx, currField, tagExpr), true)
   106  	return float64(int64(v0) % int64(v1))
   107  }
   108  
   109  type equalExprNode struct{ exprBackground }
   110  
   111  func (ee *equalExprNode) String() string {
   112  	return "=="
   113  }
   114  
   115  func newEqualExprNode() ExprNode { return &equalExprNode{} }
   116  
   117  func (ee *equalExprNode) Run(ctx context.Context, currField string, tagExpr *TagExpr) interface{} {
   118  	v0 := ee.leftOperand.Run(ctx, currField, tagExpr)
   119  	v1 := ee.rightOperand.Run(ctx, currField, tagExpr)
   120  	if v0 == v1 {
   121  		return true
   122  	}
   123  	if s0, ok := toFloat64(v0, false); ok {
   124  		if s1, ok := toFloat64(v1, true); ok {
   125  			return s0 == s1
   126  		}
   127  	}
   128  	if s0, ok := toString(v0, false); ok {
   129  		if s1, ok := toString(v1, true); ok {
   130  			return s0 == s1
   131  		}
   132  		return false
   133  	}
   134  	switch r := v0.(type) {
   135  	case bool:
   136  		r1, ok := v1.(bool)
   137  		if ok {
   138  			return r == r1
   139  		}
   140  	case nil:
   141  		return v1 == nil
   142  	}
   143  	return false
   144  }
   145  
   146  type notEqualExprNode struct{ equalExprNode }
   147  
   148  func (ne *notEqualExprNode) String() string {
   149  	return "!="
   150  }
   151  
   152  func newNotEqualExprNode() ExprNode { return &notEqualExprNode{} }
   153  
   154  func (ne *notEqualExprNode) Run(ctx context.Context, currField string, tagExpr *TagExpr) interface{} {
   155  	return !ne.equalExprNode.Run(ctx, currField, tagExpr).(bool)
   156  }
   157  
   158  type greaterExprNode struct{ exprBackground }
   159  
   160  func (ge *greaterExprNode) String() string {
   161  	return ">"
   162  }
   163  
   164  func newGreaterExprNode() ExprNode { return &greaterExprNode{} }
   165  
   166  func (ge *greaterExprNode) Run(ctx context.Context, currField string, tagExpr *TagExpr) interface{} {
   167  	v0 := ge.leftOperand.Run(ctx, currField, tagExpr)
   168  	v1 := ge.rightOperand.Run(ctx, currField, tagExpr)
   169  	if s0, ok := toFloat64(v0, false); ok {
   170  		if s1, ok := toFloat64(v1, true); ok {
   171  			return s0 > s1
   172  		}
   173  	}
   174  	if s0, ok := toString(v0, false); ok {
   175  		if s1, ok := toString(v1, true); ok {
   176  			return s0 > s1
   177  		}
   178  		return false
   179  	}
   180  	return false
   181  }
   182  
   183  type greaterEqualExprNode struct{ exprBackground }
   184  
   185  func (ge *greaterEqualExprNode) String() string {
   186  	return ">="
   187  }
   188  
   189  func newGreaterEqualExprNode() ExprNode { return &greaterEqualExprNode{} }
   190  
   191  func (ge *greaterEqualExprNode) Run(ctx context.Context, currField string, tagExpr *TagExpr) interface{} {
   192  	v0 := ge.leftOperand.Run(ctx, currField, tagExpr)
   193  	v1 := ge.rightOperand.Run(ctx, currField, tagExpr)
   194  	if s0, ok := toFloat64(v0, false); ok {
   195  		if s1, ok := toFloat64(v1, true); ok {
   196  			return s0 >= s1
   197  		}
   198  	}
   199  	if s0, ok := toString(v0, false); ok {
   200  		if s1, ok := toString(v1, true); ok {
   201  			return s0 >= s1
   202  		}
   203  		return false
   204  	}
   205  	return false
   206  }
   207  
   208  type lessExprNode struct{ exprBackground }
   209  
   210  func (le *lessExprNode) String() string {
   211  	return "<"
   212  }
   213  
   214  func newLessExprNode() ExprNode { return &lessExprNode{} }
   215  
   216  func (le *lessExprNode) Run(ctx context.Context, currField string, tagExpr *TagExpr) interface{} {
   217  	v0 := le.leftOperand.Run(ctx, currField, tagExpr)
   218  	v1 := le.rightOperand.Run(ctx, currField, tagExpr)
   219  	if s0, ok := toFloat64(v0, false); ok {
   220  		if s1, ok := toFloat64(v1, true); ok {
   221  			return s0 < s1
   222  		}
   223  	}
   224  	if s0, ok := toString(v0, false); ok {
   225  		if s1, ok := toString(v1, true); ok {
   226  			return s0 < s1
   227  		}
   228  		return false
   229  	}
   230  	return false
   231  }
   232  
   233  type lessEqualExprNode struct{ exprBackground }
   234  
   235  func (le *lessEqualExprNode) String() string {
   236  	return "<="
   237  }
   238  
   239  func newLessEqualExprNode() ExprNode { return &lessEqualExprNode{} }
   240  
   241  func (le *lessEqualExprNode) Run(ctx context.Context, currField string, tagExpr *TagExpr) interface{} {
   242  	v0 := le.leftOperand.Run(ctx, currField, tagExpr)
   243  	v1 := le.rightOperand.Run(ctx, currField, tagExpr)
   244  	if s0, ok := toFloat64(v0, false); ok {
   245  		if s1, ok := toFloat64(v1, true); ok {
   246  			return s0 <= s1
   247  		}
   248  	}
   249  	if s0, ok := toString(v0, false); ok {
   250  		if s1, ok := toString(v1, true); ok {
   251  			return s0 <= s1
   252  		}
   253  		return false
   254  	}
   255  	return false
   256  }
   257  
   258  type andExprNode struct{ exprBackground }
   259  
   260  func (ae *andExprNode) String() string {
   261  	return "&&"
   262  }
   263  
   264  func newAndExprNode() ExprNode { return &andExprNode{} }
   265  
   266  func (ae *andExprNode) Run(ctx context.Context, currField string, tagExpr *TagExpr) interface{} {
   267  	for _, e := range [2]ExprNode{ae.leftOperand, ae.rightOperand} {
   268  		if !FakeBool(e.Run(ctx, currField, tagExpr)) {
   269  			return false
   270  		}
   271  	}
   272  	return true
   273  }
   274  
   275  type orExprNode struct{ exprBackground }
   276  
   277  func (oe *orExprNode) String() string {
   278  	return "||"
   279  }
   280  
   281  func newOrExprNode() ExprNode { return &orExprNode{} }
   282  
   283  func (oe *orExprNode) Run(ctx context.Context, currField string, tagExpr *TagExpr) interface{} {
   284  	for _, e := range [2]ExprNode{oe.leftOperand, oe.rightOperand} {
   285  		if FakeBool(e.Run(ctx, currField, tagExpr)) {
   286  			return true
   287  		}
   288  	}
   289  	return false
   290  }