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 ¬EqualExprNode{} } 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 }