Documentation
¶
Overview ¶
Package rules provides a set of tools for parsing, evaluating, and working with boolean expressions in the form of rules. It includes support for variables, attributes, and rule sets.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidRule is an error indicating that a rule is invalid. ErrInvalidRule = fmt.Errorf("invalid rule") // ErrMissingDataInContext is an error indicating that there is a lack of data in the rule context. ErrMissingDataInContext = fmt.Errorf("missing data in context") // ErrMismatchedParentheses is an error indicating that there are mismatched parentheses in a rule expression. ErrMismatchedParentheses = errors.New("mismatched parentheses") // ErrEmptyExpression is an error indicating that the rule expression is empty. ErrEmptyExpression = errors.New("empty expression") // ErrInvalidExpression is an error indicating that the rule expression is invalid. ErrInvalidExpression = errors.New("invalid expression") )
Functions ¶
func NewVariable ¶
func NewVariable[T ordered](name string) variableFunc[T]
Types ¶
type Attribute ¶
type Attribute interface {
RuleElement
// contains filtered or unexported methods
}
Attribute represents a boolean value that can be used in a rule.
type AttributeDescriptor ¶
func NewAttribute ¶
func NewAttribute(name string) AttributeDescriptor
type Rule ¶
type Rule interface {
Name() string
Evaluate(ctx RuleContext) (bool, error)
}
Rule is an interface that represents a rule. It includes methods for getting the name of the rule and evaluating the rule with a given rule context to determine its boolean result.
func Parse ¶
Parse parses a rule expression and returns a Rule. The expression is a string that contains a boolean expression. The expression can contain the following operators:
- AND, OR, XOR, NOT, EQ, NEQ, GT, LT, GTE, LTE
Example ¶
package main
import (
"fmt"
"github.com/IAmRadek/rules"
)
var isPassengerEconomy = rules.NewAttribute("passengerIsEconomy")
var isPassengerGoldCardHolder = rules.NewAttribute("passengerIsGoldCardHolder")
var isPassengerSilverCardHolder = rules.NewAttribute("passengerIsSilverCardHolder")
var isPassengerDressSmart = rules.NewAttribute("passengerDressIsSmart")
var baggageWeight = rules.NewVariable[float64]("passengerCarryOnBaggageWeightKg")
var baggageAllowance = rules.NewVariable[float64]("carryOnBaggageAllowanceKg")
var suitableForUpgrade = rules.MustParse(
"suitableForUpgrade",
`passengerIsEconomy
AND (passengerIsGoldCardHolder OR passengerIsSilverCardHolder)
AND (passengerCarryOnBaggageWeightKg LTE carryOnBaggageAllowanceKg)
AND passengerDressIsSmart`,
)
func main() {
passengerContext := rules.NewContext(
isPassengerEconomy(true),
isPassengerGoldCardHolder(true),
isPassengerSilverCardHolder(false),
isPassengerDressSmart(true),
baggageWeight(4.6),
baggageAllowance(7),
)
result, err := suitableForUpgrade.Evaluate(passengerContext)
if err != nil {
panic(err)
}
fmt.Println(result)
}
Output: true
type RuleContext ¶
type RuleContext interface {
MergeWith(ctx RuleContext) RuleContext
// contains filtered or unexported methods
}
RuleContext is an interface that represents a rule context, which is a collection of rule elements. It includes methods for merging two rule contexts.
func NewContext ¶
func NewContext(elems ...RuleElement) RuleContext
Example ¶
package main
import (
"fmt"
"github.com/IAmRadek/rules"
)
var isPassengerEconomy = rules.NewAttribute("passengerIsEconomy")
var isPassengerGoldCardHolder = rules.NewAttribute("passengerIsGoldCardHolder")
var isPassengerSilverCardHolder = rules.NewAttribute("passengerIsSilverCardHolder")
var isPassengerDressSmart = rules.NewAttribute("passengerDressIsSmart")
var isPassengerDressCasual = rules.NewAttribute("passengerDressIsCasual")
var baggageWeight = rules.NewVariable[float64]("passengerCarryOnBaggageWeightKg")
var baggageAllowance = rules.NewVariable[float64]("carryOnBaggageAllowanceKg")
var suitableForUpgrade = rules.MustParse(
"suitableForUpgrade",
`passengerIsEconomy
AND (passengerIsGoldCardHolder OR passengerIsSilverCardHolder)
AND (passengerCarryOnBaggageWeightKg LTE carryOnBaggageAllowanceKg)
AND passengerDressIsSmart`,
)
func main() {
globalContext := rules.NewContext(
baggageAllowance(3),
isPassengerDressCasual(true),
)
passengerContext := rules.NewContext(
isPassengerEconomy(true),
isPassengerGoldCardHolder(true),
isPassengerSilverCardHolder(false),
isPassengerDressSmart(true),
baggageWeight(4.6),
baggageAllowance(7),
).MergeWith(globalContext)
fmt.Println(passengerContext)
result, err := suitableForUpgrade.Evaluate(passengerContext)
if err != nil {
panic(err)
}
fmt.Println(result)
}
Output: passengerIsEconomy(true), passengerIsGoldCardHolder(true), passengerIsSilverCardHolder(false), passengerDressIsSmart(true), passengerCarryOnBaggageWeightKg(4.6), carryOnBaggageAllowanceKg(7), passengerDressIsCasual(true) true
type RuleElement ¶
type RuleElement interface {
// contains filtered or unexported methods
}
RuleElement is an interface that represents a rule element, which can be an attribute, a variable, or any other element of a rule.
type RuleOverride ¶
type RuleOverride interface {
Name() string
}
type RuleSet ¶
type RuleSet interface {
AddRule(rule Rule)
AddOverride(override RuleOverride)
Evaluate(ctx RuleContext) (bool, error)
}
Example ¶
package main
import (
"fmt"
"github.com/IAmRadek/rules"
)
var isPassengerEconomy = rules.NewAttribute("passengerIsEconomy")
var isPassengerGoldCardHolder = rules.NewAttribute("passengerIsGoldCardHolder")
var isPassengerSilverCardHolder = rules.NewAttribute("passengerIsSilverCardHolder")
var isPassengerDressSmart = rules.NewAttribute("passengerDressIsSmart")
var baggageWeight = rules.NewVariable[float64]("passengerCarryOnBaggageWeightKg")
var baggageAllowance = rules.NewVariable[float64]("carryOnBaggageAllowanceKg")
var suitableForUpgrade = rules.MustParse(
"suitableForUpgrade",
`passengerIsEconomy
AND (passengerIsGoldCardHolder OR passengerIsSilverCardHolder)
AND (passengerCarryOnBaggageWeightKg LTE carryOnBaggageAllowanceKg)
AND passengerDressIsSmart`,
)
var canHaveAdditionalBaggage = rules.MustParse(
"canHaveAdditionalBaggage",
`passengerIsEconomy
AND passengerIsGoldCardHolder
AND (passengerCarryOnBaggageWeightKg LTE carryOnBaggageAllowanceKg)
AND passengerDressIsSmart`,
)
func main() {
ruleSet := rules.NewRuleSet(suitableForUpgrade, canHaveAdditionalBaggage)
ruleSet.AddOverride(canHaveAdditionalBaggage)
// Create a context for a passenger
passengerContext := rules.NewContext(
isPassengerEconomy(true),
isPassengerGoldCardHolder(false),
isPassengerSilverCardHolder(true),
isPassengerDressSmart(true),
baggageWeight(4.6),
baggageAllowance(7),
)
// Evaluate the rule set
result, err := ruleSet.Evaluate(passengerContext)
if err != nil {
panic(err)
}
fmt.Println(result)
}
Output: true
func NewRuleSet ¶
type Variable ¶
type Variable interface {
RuleElement
// contains filtered or unexported methods
}
Variable represents a value that can be used in a rule.