@@ -38,8 +38,8 @@ func getLogic(obj interface{}) (op string, params []interface{}) {
38
38
panic (fmt .Errorf ("no operator in logic" ))
39
39
}
40
40
41
- // isPrimitive returns true if obj is json primitive.
42
- func isPrimitive (obj interface {}) bool {
41
+ // IsPrimitive returns true if obj is json primitive (null/bool/float64/string) .
42
+ func IsPrimitive (obj interface {}) bool {
43
43
switch obj .(type ) {
44
44
case nil :
45
45
return true
@@ -54,15 +54,15 @@ func isPrimitive(obj interface{}) bool {
54
54
case map [string ]interface {}:
55
55
return false
56
56
default :
57
- panic (fmt .Errorf ("isPrimitive not support type %T" , obj ))
57
+ panic (fmt .Errorf ("IsPrimitive not support type %T" , obj ))
58
58
}
59
59
}
60
60
61
- // toBool returns the truthy of a json object.
61
+ // ToBool returns the truthy of a json object.
62
62
// ref:
63
63
// - http://jsonlogic.com/truthy.html
64
64
// - json-logic-js/logic.js::truthy
65
- func toBool (obj interface {}) bool {
65
+ func ToBool (obj interface {}) bool {
66
66
switch o := obj .(type ) {
67
67
case nil :
68
68
return false
@@ -78,23 +78,23 @@ func toBool(obj interface{}) bool {
78
78
// Always true
79
79
return true
80
80
default :
81
- panic (fmt .Errorf ("toBool got non-json type %T" , obj ))
81
+ panic (fmt .Errorf ("ToBool got non-json type %T" , obj ))
82
82
}
83
83
}
84
84
85
- // toNumeric converts json primitive to numeric. It should be the same as JavaScript's Number(), except:
85
+ // ToNumeric converts json primitive to numeric. It should be the same as JavaScript's Number(), except:
86
86
// - an error is returned if obj is not a json primitive.
87
87
// - an error is returned if obj is string but not well-formed.
88
88
// - the number is NaN or +Inf/-Inf.
89
- func toNumeric (obj interface {}) (f float64 , err error ) {
89
+ func ToNumeric (obj interface {}) (f float64 , err error ) {
90
90
defer func () {
91
91
if err == nil {
92
92
if math .IsNaN (f ) {
93
93
f = 0
94
- err = fmt .Errorf ("toNumeric got NaN" )
94
+ err = fmt .Errorf ("ToNumeric got NaN" )
95
95
} else if math .IsInf (f , 0 ) {
96
96
f = 0
97
- err = fmt .Errorf ("toNumeric got +Inf/-Inf" )
97
+ err = fmt .Errorf ("ToNumeric got +Inf/-Inf" )
98
98
}
99
99
}
100
100
}()
@@ -112,16 +112,16 @@ func toNumeric(obj interface{}) (f float64, err error) {
112
112
case string :
113
113
return strconv .ParseFloat (o , 64 )
114
114
case []interface {}, map [string ]interface {}:
115
- return 0 , fmt .Errorf ("toNumeric not support type %T" , obj )
115
+ return 0 , fmt .Errorf ("ToNumeric not support type %T" , obj )
116
116
default :
117
- panic (fmt .Errorf ("toNumeric got non-json type %T" , obj ))
117
+ panic (fmt .Errorf ("ToNumeric got non-json type %T" , obj ))
118
118
}
119
119
}
120
120
121
- // toString converts json primitive to string. It should be the same as JavaScript's String(), except:
121
+ // ToString converts json primitive to string. It should be the same as JavaScript's String(), except:
122
122
// - an error is returned if obj is not a json primitive.
123
123
// - obj is number NaN or +Inf/-Inf.
124
- func toString (obj interface {}) (string , error ) {
124
+ func ToString (obj interface {}) (string , error ) {
125
125
switch o := obj .(type ) {
126
126
case nil :
127
127
return "null" , nil
@@ -132,34 +132,36 @@ func toString(obj interface{}) (string, error) {
132
132
return "false" , nil
133
133
case float64 :
134
134
if math .IsNaN (o ) {
135
- return "" , fmt .Errorf ("toString got NaN" )
135
+ return "" , fmt .Errorf ("ToString got NaN" )
136
136
}
137
137
if math .IsInf (o , 0 ) {
138
- return "" , fmt .Errorf ("toString got +Inf/-Inf" )
138
+ return "" , fmt .Errorf ("ToString got +Inf/-Inf" )
139
139
}
140
140
return strconv .FormatFloat (o , 'f' , - 1 , 64 ), nil
141
141
case string :
142
142
return o , nil
143
143
case []interface {}, map [string ]interface {}:
144
- return "" , fmt .Errorf ("toString not support type %T" , obj )
144
+ return "" , fmt .Errorf ("ToString not support type %T" , obj )
145
145
default :
146
- panic (fmt .Errorf ("toString got non-json type %T" , obj ))
146
+ panic (fmt .Errorf ("ToString got non-json type %T" , obj ))
147
147
}
148
148
}
149
149
150
- type compSymbol string
150
+ // CompSymbol represents compare operator.
151
+ type CompSymbol string
151
152
152
- // compare symbol can be "<"/"<="/">"/">="
153
153
const (
154
- lt compSymbol = "<"
155
- le compSymbol = "<="
156
- gt compSymbol = ">"
157
- ge compSymbol = ">="
154
+ LT CompSymbol = "<"
155
+ LE CompSymbol = "<="
156
+ GT CompSymbol = ">"
157
+ GE CompSymbol = ">="
158
+ EQ CompSymbol = "==="
159
+ NE CompSymbol = "!=="
158
160
)
159
161
160
- // compareValues compares json primitives. It should be the same as JavaScript's "<"/"<="/">"/">=", except:
162
+ // CompareValues compares json primitives. It should be the same as JavaScript's "<"/"<="/">"/">="/"==="/"!= =", except:
161
163
// - an error is returned if any value is not a json primitive.
162
- // - any error retuend by toNumeric .
164
+ // - any error retuend by ToNumeric .
163
165
//
164
166
// ref:
165
167
// - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Less_than
@@ -172,44 +174,51 @@ const (
172
174
// > Strings are converted based on the values they contain, and are converted as NaN if they do not contain numeric values.
173
175
// > If either value is NaN, the operator returns false.
174
176
// > Otherwise the values are compared as numeric values.
175
- func compareValues (symbol compSymbol , left , right interface {}) (bool , error ) {
176
- if ! isPrimitive (left ) || ! isPrimitive (right ) {
177
+ func CompareValues (symbol CompSymbol , left , right interface {}) (bool , error ) {
178
+ if ! IsPrimitive (left ) || ! IsPrimitive (right ) {
177
179
return false , fmt .Errorf ("only primitive values can be compared" )
178
180
}
181
+ switch symbol {
182
+ case EQ :
183
+ return left == right , nil
184
+ case NE :
185
+ return left != right , nil
186
+ }
187
+
179
188
leftStr , leftIsStr := left .(string )
180
189
rightStr , rightIsStr := right .(string )
181
190
if leftIsStr && rightIsStr {
182
191
switch symbol {
183
- case lt :
192
+ case LT :
184
193
return leftStr < rightStr , nil
185
- case le :
194
+ case LE :
186
195
return leftStr <= rightStr , nil
187
- case gt :
196
+ case GT :
188
197
return leftStr > rightStr , nil
189
- case ge :
198
+ case GE :
190
199
return leftStr >= rightStr , nil
191
200
default :
192
201
panic (fmt .Errorf ("Impossible branch" ))
193
202
}
194
203
}
195
204
196
- leftNum , err := toNumeric (left )
205
+ leftNum , err := ToNumeric (left )
197
206
if err != nil {
198
207
return false , err
199
208
}
200
209
201
- rightNum , err := toNumeric (right )
210
+ rightNum , err := ToNumeric (right )
202
211
if err != nil {
203
212
return false , err
204
213
}
205
214
switch symbol {
206
- case lt :
215
+ case LT :
207
216
return leftNum < rightNum , nil
208
- case le :
217
+ case LE :
209
218
return leftNum <= rightNum , nil
210
- case gt :
219
+ case GT :
211
220
return leftNum > rightNum , nil
212
- case ge :
221
+ case GE :
213
222
return leftNum >= rightNum , nil
214
223
default :
215
224
panic (fmt .Errorf ("Impossible branch" ))
0 commit comments