/* Predicate package used to create interpreted mini languages with Go syntax - mostly to define various predicates for configuration, e.g. Latency() > 40 || ErrorRate() > 0.5. Here's an example of fully functional predicate language to deal with division remainders: // takes number and returns true or false type numberPredicate func(v int) bool // Converts one number to another type numberMapper func(v int) int // Function that creates predicate to test if the remainder is 0 func divisibleBy(divisor int) numberPredicate { return func(v int) bool { return v%divisor == 0 } } // Function - logical operator AND that combines predicates func numberAND(a, b numberPredicate) numberPredicate { return func(v int) bool { return a(v) && b(v) } } p, err := NewParser(Def{ Operators: Operators{ AND: numberAND, }, Functions: map[string]interface{}{ "DivisibleBy": divisibleBy, }, }) pr, err := p.Parse("DivisibleBy(2) && DivisibleBy(3)") if err == nil { fmt.Fatalf("Error: %v", err) } pr.(numberPredicate)(2) // false pr.(numberPredicate)(3) // false pr.(numberPredicate)(6) // true */ package predicate // Def contains supported operators (e.g. LT, GT) and functions passed in as a map. type Def struct { Operators Operators // Function matching is case sensitive, e.g. Len is different from len Functions map[string]interface{} } // Operators contain functions for equality and logical comparison. type Operators struct { EQ interface{} NEQ interface{} LT interface{} GT interface{} LE interface{} GE interface{} OR interface{} AND interface{} } // Parser takes the string with expression and calls the operators and functions. type Parser interface { Parse(string) (interface{}, error) }