xpress is inspired by JsonLogic but aims to be terser at the cost of reduced features. It ONLY supports logical operators.
xpress follows similar principles as JsonLogic
- Terse(er).
- Readable. As close to infix expressions as possible
- Consistent. 3-tuple expressions
["operand", "operator", "operand"]
joined byAND
and/orOR
- Secure. We never
eval()
- Flexible. Easy to add new operators, easy to build complex structures
- Only logical operators are supported.
- Unary operators are not supported.
xpress.evaluate([1, "==", 1])
# True
This is a simple rule, equivalent to 1 == 1. A few things about the format:
- The operator is always at the 2nd position(index: 1) in the expression 3-tuple. There is only one operator per expression.
- The operands are either a literal, a variable or an array of literals and/or variables.
- Each value can be a string, number, boolean, array (non-associative), or null
Here we’re beginning to nest rules.
xpress.evaluate([[3, ">", 1], "and", [1, "<", 3]])
# True
In an infix language (like Python) this could be written as:
( (3 > 1) and (1 < 3) )
Obviously these rules aren’t very interesting if they can only take static literal data. Typically xpress will be called with a rule object and a data object. You can use the var operator to get attributes of the data object. Here’s a complex rule that mixes literals and data. The pie isn’t ready to eat unless it’s cooler than 110 degrees, and filled with apples.
rules = [["var:temp", "<", 110], "and", ["var:pie.filling", "==", "apple"]]
data = { "temp" : 100, "pie" : { "filling" : "apple" } }
xpress.evaluate(rules, data)
# True
Sometimes the rule you want to process is “Always” or “Never.” If the first parameter passed to jsonLogic is a non-object, non-associative-array, it is returned immediately.
# Always
xpress.evaluate(True, data_will_be_ignored)
# True
# Never
xpress.evaluate(False, i_wasnt_even_supposed_to_be_here)
# False
var
==
===
!=
!==
or
and
>
,>=
,<
and<=
in
in