Documentation
¶
Overview ¶
package gorulesengine provides a powerful and flexible rules engine for Go. It allows you to define business rules in JSON or code, evaluate complex conditions, and trigger events based on dynamic facts.
Index ¶
- Constants
- func DefaultPathResolver(value interface{}, path string) (interface{}, error)
- func RegisterOperator(opType OperatorType, operator Operator)
- type Almanac
- func (a *Almanac) AddFact(id FactID, valueOrMethod interface{}, opts ...FactOption) error
- func (a *Almanac) AddFacts(facts ...*Fact)
- func (a *Almanac) GetConditionResultFromCache(key string) (interface{}, bool)
- func (a *Almanac) GetFactValue(factID FactID, params map[string]interface{}, path string) (interface{}, error)
- func (a *Almanac) GetFactValueFromCache(factID FactID) (interface{}, bool)
- func (a *Almanac) GetFacts() map[FactID]*Fact
- func (a *Almanac) GetOptions() map[string]interface{}
- func (a *Almanac) IsConditionCachingEnabled() bool
- func (a *Almanac) PreCacheFactValue(fact *Fact)
- func (a *Almanac) SetConditionResultCache(key string, result interface{})
- func (a *Almanac) TraversePath(data interface{}, path string) (interface{}, error)
- type AlmanacError
- type AlmanacOption
- type Condition
- func Contains(fact string, value interface{}) *Condition
- func Equal(fact string, value interface{}) *Condition
- func GreaterThan(fact string, value interface{}) *Condition
- func GreaterThanInclusive(fact string, value interface{}) *Condition
- func In(fact string, values interface{}) *Condition
- func LessThan(fact string, value interface{}) *Condition
- func LessThanInclusive(fact string, value interface{}) *Condition
- func NotContains(fact string, value interface{}) *Condition
- func NotEqual(fact string, value interface{}) *Condition
- func NotIn(fact string, values interface{}) *Condition
- func Regex(fact string, pattern string) *Condition
- type ConditionError
- type ConditionNode
- type ConditionNodeResult
- type ConditionResult
- type ConditionSet
- func (cs *ConditionSet) Compile() error
- func (cs *ConditionSet) Evaluate(almanac *Almanac) (*ConditionSetResult, error)
- func (cs *ConditionSet) GetCacheKey() (string, error)
- func (cs *ConditionSet) GetRequiredFacts() []FactID
- func (cs *ConditionSet) ReorderNodes(nodes []ConditionNode, almanac *Almanac) ([]ConditionNode, error)
- type ConditionSetResult
- type ConditionType
- type ContainsOperator
- type Engine
- func (e *Engine) AddRule(rule *Rule)
- func (e *Engine) AddRules(rules ...*Rule)
- func (e *Engine) ClearRules()
- func (e *Engine) GenerateResponse() *EngineResponse
- func (e *Engine) GetRules() []*Rule
- func (e *Engine) HandleEvent(eventName string, ruleName string, result bool, almanac *Almanac, ...) error
- func (e *Engine) ReduceResults() map[string]bool
- func (e *Engine) RegisterEvent(event Event)
- func (e *Engine) RegisterEvents(events ...Event)
- func (e *Engine) Results() map[string]*RuleResult
- func (e *Engine) Run(almanac *Almanac) (*Engine, error)
- func (e *Engine) SetEventHandler(handler EventHandler)
- func (e *Engine) SetRules(rules []*Rule)
- type EngineOption
- func WithAuditTrace() EngineOption
- func WithConditionCaching() EngineOption
- func WithMetrics(collector MetricsCollector) EngineOption
- func WithParallelExecution(workers int) EngineOption
- func WithPrioritySorting(o *SortRule) EngineOption
- func WithSmartSkip() EngineOption
- func WithoutAuditTrace() EngineOption
- func WithoutConditionCaching() EngineOption
- func WithoutParallelExecution() EngineOption
- func WithoutPrioritySorting() EngineOption
- type EngineResponse
- type EqualOperator
- type ErrorType
- type Event
- type EventContext
- type EventHandler
- type EventMode
- type EventOutcome
- type EventResponse
- type Fact
- func (f *Fact) Calculate(params map[string]interface{}) interface{}
- func (f *Fact) FactType() string
- func (f *Fact) GetCacheKey() (string, error)
- func (f *Fact) GetOption(key string) (interface{}, bool)
- func (f *Fact) HasOption(key string) bool
- func (f *Fact) ID() FactID
- func (f *Fact) IsDynamic() bool
- func (f *Fact) Metadata() map[string]interface{}
- func (f *Fact) ValueOrMethod() interface{}
- type FactError
- type FactID
- type FactOption
- type GreaterThanInclusiveOperator
- type GreaterThanOperator
- type HTTPRuleProvider
- type HotReloader
- type InOperator
- type LessThanInclusiveOperator
- type LessThanOperator
- type MetricsCollector
- type NotContainsOperator
- type NotEqualOperator
- type NotInOperator
- type Operator
- type OperatorError
- type OperatorType
- type PathResolver
- type RegexOperator
- type Rule
- type RuleBuilder
- func (rb *RuleBuilder) Build() *Rule
- func (rb *RuleBuilder) WithConditions(node ConditionNode) *RuleBuilder
- func (rb *RuleBuilder) WithName(name string) *RuleBuilder
- func (rb *RuleBuilder) WithOnFailure(eventNames ...string) *RuleBuilder
- func (rb *RuleBuilder) WithOnFailureEvent(event RuleEvent) *RuleBuilder
- func (rb *RuleBuilder) WithOnSuccess(eventNames ...string) *RuleBuilder
- func (rb *RuleBuilder) WithOnSuccessEvent(event RuleEvent) *RuleBuilder
- func (rb *RuleBuilder) WithPriority(priority int) *RuleBuilder
- type RuleEngineError
- type RuleError
- type RuleEvent
- type RuleProvider
- type RuleResult
- type SortRule
Constants ¶
const ( // SortByPriority is the string constant for priority-based sorting SortByPriority = "priority" // EngineOptionKeyCacheConditions is the option key for condition results caching EngineOptionKeyCacheConditions = "cacheConditions" // EngineOptionKeySmartSkip is the option key for enabling smart skip of rules EngineOptionKeySmartSkip = "smartSkip" // EngineOptionKeyAuditTrace is the option key for enabling rich audit trace EngineOptionKeyAuditTrace = "auditTrace" // EngineOptionKeyParallel is the option key for enabling parallel execution EngineOptionKeyParallel = "parallel" // EngineOptionKeyWorkerCount is the option key for specifying the number of workers for parallel execution EngineOptionKeyWorkerCount = "workerCount" // SortDefault is the default sort order SortDefault SortRule = iota // SortRuleASC sorts rules in ascending order SortRuleASC // SortRuleDESC sorts rules in descending order SortRuleDESC )
const ( // DecisionAuthorize indicates that conditions were met. DecisionAuthorize = "authorize" // DecisionDecline indicates that conditions were not met. DecisionDecline = "decline" )
const AlmanacOptionKeyAllowUndefinedFacts = "allowUndefinedFacts"
AlmanacOptionKeyAllowUndefinedFacts is the option key for allowing undefined facts.
const AlmanacOptionKeyCacheConditions = "cacheConditions"
AlmanacOptionKeyCacheConditions is the option key for enabling condition results caching.
const ConstantFact = "__constant_fact__"
ConstantFact identifies a fact with a static, pre-defined value.
const DynamicFact = "__dynamic_fact__"
DynamicFact identifies a fact that computes its value dynamically using a function.
const FactOptionKeyCache = "cache"
FactOptionKeyCache is the key for the caching option in fact options.
const FactOptionKeyPriority = "priority"
FactOptionKeyPriority is the key for the priority option in fact options.
Variables ¶
This section is empty.
Functions ¶
func DefaultPathResolver ¶
DefaultPathResolver implements JSONPath resolution for accessing nested fact values. Example: "$.user.profile.age" accesses deeply nested data.
func RegisterOperator ¶
func RegisterOperator(opType OperatorType, operator Operator)
RegisterOperator registers a custom operator in the global operator registry. This allows you to extend the engine with custom comparison logic.
Example:
type StartsWithOperator struct{}
func (o *StartsWithOperator) Evaluate(factValue, compareValue interface{}) (bool, error) {
str, ok1 := factValue.(string)
prefix, ok2 := compareValue.(string)
if !ok1 || !ok2 {
return false, fmt.Errorf("both values must be strings")
}
return strings.HasPrefix(str, prefix), nil
}
gre.RegisterOperator("starts_with", &StartsWithOperator{})
Types ¶
type Almanac ¶
type Almanac struct {
// contains filtered or unexported fields
}
Almanac stores facts and their computed values during rule evaluation. It maintains a cache for fact values, tracks events, and manages rule results. Almanac is thread-safe for concurrent access.
func NewAlmanac ¶
func NewAlmanac(opts ...AlmanacOption) *Almanac
NewAlmanac creates a new Almanac instance with the provided facts and options. The almanac is initialized with default settings including undefined fact handling.
Example:
almanac := gre.NewAlmanac([]*gre.Fact{})
almanac.AddFact("age", 25)
almanac.AddFact("country", "FR")
func (*Almanac) AddFact ¶
func (a *Almanac) AddFact(id FactID, valueOrMethod interface{}, opts ...FactOption) error
AddFact adds a fact to the almanac. The valueOrMethod can be either a static value or a function for dynamic facts. Optional FactOptions can be provided to configure caching and priority.
Example:
// Static fact
almanac.AddFact("age", 25)
// Dynamic fact
almanac.AddFact("temperature", func(params map[string]interface{}) interface{} {
return fetchTemperature()
})
func (*Almanac) GetConditionResultFromCache ¶
GetConditionResultFromCache retrieves a condition result from the cache.
func (*Almanac) GetFactValue ¶
func (a *Almanac) GetFactValue(factID FactID, params map[string]interface{}, path string) (interface{}, error)
GetFactValue retrieves the value of a fact by its ID. For dynamic facts, params can be passed to the computation function. The path parameter allows accessing nested values using JSONPath.
Example:
// Simple fact access
age, _ := almanac.GetFactValue("age", nil, "")
// Nested access with JSONPath
city, _ := almanac.GetFactValue("user", nil, "$.address.city")
func (*Almanac) GetFactValueFromCache ¶
GetFactValueFromCache retrieves a fact value directly from the cache
func (*Almanac) GetOptions ¶
GetOptions returns the almanac options
func (*Almanac) IsConditionCachingEnabled ¶
IsConditionCachingEnabled checks if condition caching is enabled in the almanac.
func (*Almanac) PreCacheFactValue ¶
PreCacheFactValue computes and caches the value of a fact if caching is enabled.
func (*Almanac) SetConditionResultCache ¶
SetConditionResultCache stores a condition result in the cache.
func (*Almanac) TraversePath ¶
TraversePath is a helper to traverse nested structures based on a path expression. It uses the configured PathResolver to access nested values within complex data structures.
type AlmanacError ¶
type AlmanacError struct {
Payload string // Context about what was being accessed
Err error // Underlying error
}
AlmanacError represents an error that occurred while accessing or managing facts in the almanac.
func (*AlmanacError) Error ¶
func (e *AlmanacError) Error() string
Error methods to convert to RuleEngineError
func (*AlmanacError) Unwrap ¶
func (e *AlmanacError) Unwrap() error
Unwrap returns the wrapped error
type AlmanacOption ¶
type AlmanacOption func(*Almanac)
AlmanacOption defines a functional option for configuring an Almanac.
func AllowUndefinedFacts ¶
func AllowUndefinedFacts() AlmanacOption
AllowUndefinedFacts configures the almanac to return nil instead of errors for undefined facts. This is useful when you want to gracefully handle missing data.
func WithAlmanacConditionCaching ¶
func WithAlmanacConditionCaching() AlmanacOption
WithAlmanacConditionCaching enables caching of condition results.
type Condition ¶
type Condition struct {
Fact FactID `json:"fact"` // The fact identifier to evaluate
Operator OperatorType `json:"operator"` // The comparison operator to use
Value interface{} `json:"value"` // The expected value to compare against
Path string `json:"path,omitempty"` // Optional JSONPath to access nested fact values
Params map[string]interface{} `json:"params,omitempty"` // Optional parameters for dynamic facts
// contains filtered or unexported fields
}
Condition represents a single condition that compares a fact value against an expected value using an operator. Conditions can optionally use JSONPath to access nested values within facts.
Example:
condition := &gre.Condition{
Fact: "age",
Operator: "greater_than",
Value: 18,
}
func GreaterThan ¶
GreaterThan creates a condition that checks if fact > value.
func GreaterThanInclusive ¶
GreaterThanInclusive creates a condition that checks if fact >= value.
func LessThanInclusive ¶
LessThanInclusive creates a condition that checks if fact <= value.
func NotContains ¶
NotContains creates a condition that checks if fact does not contain value.
func (*Condition) Compile ¶
Compile pre-calculates properties of the condition to speed up evaluation.
func (*Condition) Evaluate ¶
func (c *Condition) Evaluate(almanac *Almanac) (*ConditionResult, error)
Evaluate evaluates the condition against the almanac
func (*Condition) GetCacheKey ¶
GetCacheKey generates a unique cache key for the condition.
func (*Condition) GetRequiredFacts ¶
GetRequiredFacts returns the list of facts required by this condition.
type ConditionError ¶
type ConditionError struct {
Condition Condition // The condition that failed
Err error // Underlying error
}
ConditionError represents an error that occurred while evaluating a condition.
func (*ConditionError) Error ¶
func (e *ConditionError) Error() string
Error methods to convert to RuleEngineError
func (*ConditionError) Unwrap ¶
func (e *ConditionError) Unwrap() error
Unwrap returns the wrapped error
type ConditionNode ¶
type ConditionNode struct {
Condition *Condition // A single condition to evaluate
SubSet *ConditionSet // A nested set of conditions
}
ConditionNode represents either a single Condition or a nested ConditionSet. This allows for recursive nesting of conditions to build complex boolean expressions.
func (*ConditionNode) GetRequiredFacts ¶
func (n *ConditionNode) GetRequiredFacts() []FactID
GetRequiredFacts returns the list of facts required by this condition node.
func (*ConditionNode) UnmarshalJSON ¶
func (n *ConditionNode) UnmarshalJSON(data []byte) error
UnmarshalJSON implements custom JSON unmarshaling for ConditionNode. It attempts to unmarshal either a Condition or a ConditionSet from the JSON data.
type ConditionNodeResult ¶
type ConditionNodeResult struct {
Condition *ConditionResult `json:"condition,omitempty"`
ConditionSet *ConditionSetResult `json:"conditionSet,omitempty"`
}
ConditionNodeResult represents the result of a single node within a ConditionSet.
type ConditionResult ¶
type ConditionResult struct {
Fact FactID `json:"fact"`
Operator OperatorType `json:"operator"`
Value interface{} `json:"value"` // The value to compare against
FactValue interface{} `json:"factValue"` // The actual value fetched from the Almanac
Path string `json:"path,omitempty"` // The JSONPath used, if any
Result bool `json:"result"`
Error string `json:"error,omitempty"`
}
ConditionResult represents the detailed evaluation result of a single Condition.
type ConditionSet ¶
type ConditionSet struct {
All []ConditionNode `json:"all,omitempty"` // All conditions must be true (AND)
Any []ConditionNode `json:"any,omitempty"` // At least one condition must be true (OR)
None []ConditionNode `json:"none,omitempty"` // No conditions must be true (NOT)
// contains filtered or unexported fields
}
ConditionSet represents a group of conditions combined with logical operators (all/any/none). ConditionSets can be nested to create complex boolean logic.
Example:
conditionSet := gre.ConditionSet{
All: []gre.ConditionNode{
{Condition: &condition1},
{Condition: &condition2},
},
}
func All ¶
func All(conditions ...*Condition) ConditionSet
All creates a ConditionSet where all conditions must be true.
func AllSets ¶
func AllSets(sets ...ConditionSet) ConditionSet
AllSets creates a ConditionSet where all nested ConditionSets must be true.
func Any ¶
func Any(conditions ...*Condition) ConditionSet
Any creates a ConditionSet where at least one condition must be true.
func AnySets ¶
func AnySets(sets ...ConditionSet) ConditionSet
AnySets creates a ConditionSet where at least one nested ConditionSet must be true.
func None ¶
func None(conditions ...*Condition) ConditionSet
None creates a ConditionSet where no conditions must be true.
func NoneSets ¶
func NoneSets(sets ...ConditionSet) ConditionSet
NoneSets creates a ConditionSet where no nested ConditionSets must be true.
func (*ConditionSet) Compile ¶
func (cs *ConditionSet) Compile() error
Compile pre-calculates properties for the entire condition set.
func (*ConditionSet) Evaluate ¶
func (cs *ConditionSet) Evaluate(almanac *Almanac) (*ConditionSetResult, error)
Evaluate evaluates the condition set against the almanac
func (*ConditionSet) GetCacheKey ¶
func (cs *ConditionSet) GetCacheKey() (string, error)
GetCacheKey generates a unique cache key for the condition set.
func (*ConditionSet) GetRequiredFacts ¶
func (cs *ConditionSet) GetRequiredFacts() []FactID
GetRequiredFacts returns the list of all facts required by this condition set.
func (*ConditionSet) ReorderNodes ¶
func (cs *ConditionSet) ReorderNodes(nodes []ConditionNode, almanac *Almanac) ([]ConditionNode, error)
ReorderNodes puts cached conditions at the beginning of the slice to optimize short-circuiting.
type ConditionSetResult ¶
type ConditionSetResult struct {
Type ConditionType `json:"type"`
Result bool `json:"result"`
Results []ConditionNodeResult `json:"results"`
}
ConditionSetResult represents the evaluation result of a ConditionSet (All, Any, or None).
type ConditionType ¶
type ConditionType string
ConditionType represents the type of logical operator for combining conditions.
const ( // AllType represents a logical AND - all conditions must be true. AllType ConditionType = "all" // AnyType represents a logical OR - at least one condition must be true. AnyType ConditionType = "any" // NoneType represents a logical NOT - no conditions must be true. NoneType ConditionType = "none" )
type ContainsOperator ¶
type ContainsOperator struct{}
ContainsOperator checks if factValue contains compareValue (for strings and arrays).
func (*ContainsOperator) Evaluate ¶
func (o *ContainsOperator) Evaluate(factValue interface{}, compareValue interface{}) (bool, error)
Evaluate checks if factValue contains compareValue. For strings, checks substring containment. For arrays/slices, checks element presence.
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine is the core rules engine that manages rules, facts, and event handlers. It evaluates rules against facts and triggers events when rules match.
func NewEngine ¶
func NewEngine(opts ...EngineOption) *Engine
NewEngine creates a new rules engine instance
func (*Engine) ClearRules ¶
func (e *Engine) ClearRules()
ClearRules removes all rules from the engine.
func (*Engine) GenerateResponse ¶
func (e *Engine) GenerateResponse() *EngineResponse
GenerateResponse builds the formatted Response object for JSON Marshalling.
func (*Engine) HandleEvent ¶
func (e *Engine) HandleEvent(eventName string, ruleName string, result bool, almanac *Almanac, ruleParams map[string]interface{}) error
HandleEvent invokes the event handler for the given event with context. Supports both synchronous and asynchronous execution based on event mode. ruleParams are optional parameters passed from the rule itself and combined with event defaults.
func (*Engine) ReduceResults ¶
ReduceResults converts a map of detailed RuleResults to a simple map of booleans.
func (*Engine) RegisterEvent ¶
RegisterEvent registers a named handler that can be referenced by rules. Handlers are invoked when rules succeed.
func (*Engine) RegisterEvents ¶
RegisterEvents registers a named handler that can be referenced by rules. Handlers are invoked when rules succeed.
func (*Engine) Results ¶
func (e *Engine) Results() map[string]*RuleResult
Results returns the detailed results of rule evaluations.
func (*Engine) Run ¶
Run executes all rules in the engine against the provided almanac. Rules are evaluated in priority order (higher priority first). Returns a slice of RuleResults containing the outcome of each rule evaluation. If any error occurs during evaluation, execution stops and the error is returned. Run executes all registered rules against the facts in the provided Almanac. It returns a map of rule names to their evaluation results.
func (*Engine) SetEventHandler ¶
func (e *Engine) SetEventHandler(handler EventHandler)
SetEventHandler sets the global event handler for the engine
type EngineOption ¶
type EngineOption func(*Engine)
EngineOption defines a function type for configuring the Engine.
func WithAuditTrace ¶
func WithAuditTrace() EngineOption
WithAuditTrace enables detailed audit trace for rule evaluations.
func WithConditionCaching ¶
func WithConditionCaching() EngineOption
WithConditionCaching enables condition caching for all rules evaluated by the engine.
func WithMetrics ¶
func WithMetrics(collector MetricsCollector) EngineOption
WithMetrics configures the engine with a metrics collector.
func WithParallelExecution ¶
func WithParallelExecution(workers int) EngineOption
WithParallelExecution enables parallel execution of rules.
func WithPrioritySorting ¶
func WithPrioritySorting(o *SortRule) EngineOption
WithPrioritySorting configures the engine to sort rules by priority before evaluation.
func WithSmartSkip ¶
func WithSmartSkip() EngineOption
WithSmartSkip enables skipping rules that depend on facts not present in the almanac.
func WithoutAuditTrace ¶
func WithoutAuditTrace() EngineOption
WithoutAuditTrace disables detailed audit trace for rule evaluations.
func WithoutConditionCaching ¶
func WithoutConditionCaching() EngineOption
WithoutConditionCaching disables condition caching for all rules evaluated by the engine.
func WithoutParallelExecution ¶
func WithoutParallelExecution() EngineOption
WithoutParallelExecution disables parallel execution of rules.
func WithoutPrioritySorting ¶
func WithoutPrioritySorting() EngineOption
WithoutPrioritySorting configures the engine to not sort rules by priority.
type EngineResponse ¶
type EngineResponse struct {
Decision string `json:"decision"` // DecisionAuthorize or DecisionDecline
Reason interface{} `json:"reason"` // Detail of conditions (if AuditTrace is active)
Events []EventResponse `json:"events"` // List of triggered events
Metadata map[string]interface{} `json:"metadata"` // Metadata from facts or other sources
}
EngineResponse represents the final formatted structure for your JSON response.
type EqualOperator ¶
type EqualOperator struct{}
EqualOperator checks if two values are equal.
func (*EqualOperator) Evaluate ¶
func (o *EqualOperator) Evaluate(factValue interface{}, compareValue interface{}) (bool, error)
Evaluate checks if two values are equal using deep equality comparison. Returns false if the values have different types or if either value is nil.
type ErrorType ¶
type ErrorType string
ErrorType identifies the category of error that occurred.
const ( // ErrEngine indicates a general engine execution error. ErrEngine ErrorType = "ENGINE_ERROR" // ErrAlmanac indicates an error related to the almanac or fact management. ErrAlmanac ErrorType = "ALMANAC_ERROR" // ErrFact indicates an error computing or accessing a fact value. ErrFact ErrorType = "FACT_ERROR" // ErrRule indicates an error in rule definition or structure. ErrRule ErrorType = "RULE_ERROR" // ErrCondition indicates an error evaluating a condition. ErrCondition ErrorType = "CONDITION_ERROR" // ErrOperator indicates an error with an operator (not found, invalid, etc.). ErrOperator ErrorType = "OPERATOR_ERROR" // ErrEvent indicates an error related to event handling. ErrEvent ErrorType = "EVENT_ERROR" // ErrJSON indicates an error parsing or unmarshaling JSON. ErrJSON ErrorType = "JSON_ERROR" // ErrLoader indicates an error related to loading rules or data. ErrLoader ErrorType = "LOADER_ERROR" )
type Event ¶
type Event struct {
Name string // Name of the event
Params map[string]interface{} // Optional parameters passed with the event
Action func(EventContext) error // Action to execute when the event is handled
Mode EventMode // Execution mode (sync or async)
}
Event represents an event triggered by a rule when its conditions are met. Events can carry additional parameters in the Params map.
type EventContext ¶
type EventContext struct {
RuleName string // Name of the rule that triggered the event
Result bool // Result of the rule evaluation (true=success, false=failure)
Almanac *Almanac // Reference to the almanac used for evaluation
Timestamp time.Time // When the event was triggered
Params map[string]interface{} // Additional parameters from the event
}
EventContext provides context information about the rule execution that triggered an event
type EventHandler ¶
type EventHandler interface {
Handle(event Event, ctx EventContext) error
}
EventHandler defines the interface for handling events triggered by rules.
type EventOutcome ¶
type EventOutcome string
EventOutcome represents an event outcome triggered by a rule.
const EventOutcomeFailure EventOutcome = "failure"
EventOutcomeFailure represents a failed event outcome.
const EventOutcomeSuccess EventOutcome = "success"
EventOutcomeSuccess represents a successful event outcome.
type EventResponse ¶
type EventResponse struct {
Type string `json:"type"`
Params map[string]interface{} `json:"params,omitempty"`
}
EventResponse represents a simplified event.
type Fact ¶
type Fact struct {
// contains filtered or unexported fields
}
Fact represents a piece of data (fact) that can be used in rule conditions. Facts can be static values or dynamic functions that compute values on demand.
Example:
// Static fact
fact := gre.NewFact("age", 25)
// Dynamic fact
fact := gre.NewFact("temperature", func(params map[string]interface{}) interface{} {
return fetchTemperatureFromAPI()
})
func NewFact ¶
func NewFact(id FactID, valueOrMethod interface{}, opts ...FactOption) Fact
NewFact creates a new fact with the given ID and value or computation function. If valueOrMethod is a function, the fact is dynamic and will compute its value on demand. Otherwise, the fact is static with a constant value.
Options can be provided to customize caching and priority behavior.
Example:
// Static fact
fact := gre.NewFact("age", 25)
// Dynamic fact with custom options
fact := gre.NewFact("temperature",
func(params map[string]interface{}) interface{} {
return fetchTemperature()
},
gre.WithCache(),
gre.WithPriority(10),
)
func (*Fact) Calculate ¶
Calculate executes the dynamic fact method or returns the constant fact value
func (*Fact) GetCacheKey ¶
GetCacheKey generates a unique cache key for the fact if it's cached
func (*Fact) IsDynamic ¶
IsDynamic returns true if the fact computes its value dynamically using a function.
func (*Fact) ValueOrMethod ¶
func (f *Fact) ValueOrMethod() interface{}
ValueOrMethod returns the fact's value (for static facts) or computation function (for dynamic facts).
type FactError ¶
FactError represents an error that occurred while computing or accessing a fact value.
type FactOption ¶
type FactOption func(*Fact)
FactOption defines a functional option for configuring facts.
func WithCache ¶
func WithCache() FactOption
WithCache enables caching for dynamic facts. When enabled, the fact's value will be computed once and reused.
func WithMetadata ¶
func WithMetadata(metadata map[string]interface{}) FactOption
WithMetadata adds metadata to the fact.
func WithPriority ¶
func WithPriority(priority int) FactOption
WithPriority sets the evaluation priority of the fact. Higher priority facts may be evaluated before lower priority facts.
func WithoutCache ¶
func WithoutCache() FactOption
WithoutCache disables caching for facts. When disabled, dynamic facts will be re-evaluated on each access.
type GreaterThanInclusiveOperator ¶
type GreaterThanInclusiveOperator struct{}
GreaterThanInclusiveOperator checks if factValue >= compareValue.
func (*GreaterThanInclusiveOperator) Evaluate ¶
func (o *GreaterThanInclusiveOperator) Evaluate(factValue interface{}, compareValue interface{}) (bool, error)
Evaluate checks if factValue is greater than or equal to compareValue. Both values must be numeric types.
type GreaterThanOperator ¶
type GreaterThanOperator struct{}
GreaterThanOperator checks if factValue > compareValue.
func (*GreaterThanOperator) Evaluate ¶
func (o *GreaterThanOperator) Evaluate(factValue interface{}, compareValue interface{}) (bool, error)
Evaluate checks if factValue is greater than compareValue. Both values must be numeric types.
type HTTPRuleProvider ¶
HTTPRuleProvider implements RuleProvider for fetching rules from a URL.
func NewHTTPRuleProvider ¶
func NewHTTPRuleProvider(url string) *HTTPRuleProvider
NewHTTPRuleProvider creates a new HTTP rule provider.
func (*HTTPRuleProvider) FetchRules ¶
func (p *HTTPRuleProvider) FetchRules(ctx context.Context) ([]*Rule, error)
FetchRules fetches rules from the configured URL. It expects a JSON array of rules.
type HotReloader ¶
type HotReloader struct {
// contains filtered or unexported fields
}
HotReloader manages the periodic reloading of rules from a provider.
func NewHotReloader ¶
func NewHotReloader(engine *Engine, provider RuleProvider, interval time.Duration) *HotReloader
NewHotReloader creates a new hot reloader for an engine.
func (*HotReloader) OnError ¶
func (h *HotReloader) OnError(callback func(error))
OnError sets a callback to be called whenever an error occurs during reload.
func (*HotReloader) OnUpdate ¶
func (h *HotReloader) OnUpdate(callback func([]*Rule))
OnUpdate sets a callback to be called whenever rules are updated.
func (*HotReloader) Start ¶
func (h *HotReloader) Start(ctx context.Context)
Start begins the periodic reloading process.
type InOperator ¶
type InOperator struct{}
InOperator checks if factValue is contained in compareValue (array).
func (*InOperator) Evaluate ¶
func (o *InOperator) Evaluate(factValue interface{}, compareValue interface{}) (bool, error)
Evaluate checks if factValue is contained in the compareValue array. compareValue must be a slice or array.
type LessThanInclusiveOperator ¶
type LessThanInclusiveOperator struct{}
LessThanInclusiveOperator checks if factValue <= compareValue.
func (*LessThanInclusiveOperator) Evaluate ¶
func (o *LessThanInclusiveOperator) Evaluate(factValue interface{}, compareValue interface{}) (bool, error)
Evaluate checks if factValue is less than or equal to compareValue. Both values must be numeric types.
type LessThanOperator ¶
type LessThanOperator struct{}
LessThanOperator checks if factValue < compareValue.
func (*LessThanOperator) Evaluate ¶
func (o *LessThanOperator) Evaluate(factValue interface{}, compareValue interface{}) (bool, error)
Evaluate checks if factValue is less than compareValue. Both values must be numeric types.
type MetricsCollector ¶
type MetricsCollector interface {
// ObserveRuleEvaluation records the result and duration of a single rule evaluation.
ObserveRuleEvaluation(ruleName string, result bool, duration time.Duration)
// ObserveEngineRun records the total duration and rule count of an engine execution.
ObserveEngineRun(ruleCount int, duration time.Duration)
// ObserveEventExecution records the duration and result of an event handler execution.
ObserveEventExecution(eventName string, ruleName string, result bool, duration time.Duration)
}
MetricsCollector defines an interface for monitoring the rules engine's performance and execution results. Implementations can use Prometheus, OpenTelemetry, or other monitoring systems.
type NotContainsOperator ¶
type NotContainsOperator struct{}
NotContainsOperator checks if factValue does not contain compareValue.
func (*NotContainsOperator) Evaluate ¶
func (o *NotContainsOperator) Evaluate(factValue interface{}, compareValue interface{}) (bool, error)
Evaluate checks if factValue does not contain compareValue. Returns the inverse of the ContainsOperator result.
type NotEqualOperator ¶
type NotEqualOperator struct{}
NotEqualOperator checks if two values are not equal.
func (*NotEqualOperator) Evaluate ¶
func (o *NotEqualOperator) Evaluate(factValue interface{}, compareValue interface{}) (bool, error)
Evaluate checks if two values are not equal. Returns the inverse of the EqualOperator result.
type NotInOperator ¶
type NotInOperator struct{}
NotInOperator checks if factValue is not contained in compareValue (array).
func (*NotInOperator) Evaluate ¶
func (o *NotInOperator) Evaluate(factValue interface{}, compareValue interface{}) (bool, error)
Evaluate checks if factValue is not contained in the compareValue array. Returns the inverse of the InOperator result.
type Operator ¶
type Operator interface {
// Evaluate compares a fact value against a condition value and returns true if the comparison succeeds.
Evaluate(factValue interface{}, compareValue interface{}) (bool, error)
}
Operator defines the interface for all comparison operators. Custom operators can be registered by implementing this interface.
func GetOperator ¶
func GetOperator(opType OperatorType) (Operator, error)
GetOperator retrieves an operator from the registry by its type. Returns an error if the operator is not registered.
type OperatorError ¶
type OperatorError struct {
Operator OperatorType // The operator that failed
Value interface{} // The fact value being compared
CompareValue interface{} // The expected value
Err error // Underlying error
}
OperatorError represents an error related to a specific operator evaluation.
func (*OperatorError) Error ¶
func (e *OperatorError) Error() string
Error methods to convert to RuleEngineError
func (*OperatorError) Unwrap ¶
func (e *OperatorError) Unwrap() error
Unwrap returns the wrapped error
type OperatorType ¶
type OperatorType string
OperatorType represents the type of comparison operator used in conditions.
const ( OperatorEqual OperatorType = "equal" // OperatorNotEqual checks if the fact value is not equal to the condition value. OperatorNotEqual OperatorType = "not_equal" // OperatorLessThan checks if the fact value is less than the condition value. OperatorLessThan OperatorType = "less_than" // OperatorLessThanInclusive checks if the fact value is less than or equal to the condition value. OperatorLessThanInclusive OperatorType = "less_than_inclusive" // OperatorGreaterThan checks if the fact value is greater than the condition value. OperatorGreaterThan OperatorType = "greater_than" // OperatorGreaterThanInclusive checks if the fact value is greater than or equal to the condition value. OperatorGreaterThanInclusive OperatorType = "greater_than_inclusive" // OperatorIn checks if the fact value is contained in the condition value (array). OperatorIn OperatorType = "in" // OperatorNotIn checks if the fact value is not contained in the condition value (array). OperatorNotIn OperatorType = "not_in" // OperatorContains checks if the fact value contains the condition value (for strings and arrays). OperatorContains OperatorType = "contains" // OperatorNotContains checks if the fact value does not contain the condition value. OperatorNotContains OperatorType = "not_contains" // OperatorRegex checks if the fact value matches the regex pattern in the condition value. OperatorRegex OperatorType = "regex" )
OperatorEqual checks if the fact value equals the condition value.
type PathResolver ¶
PathResolver resolves nested values within facts using a path expression (e.g., JSONPath).
type RegexOperator ¶
type RegexOperator struct{}
RegexOperator checks if factValue matches the regex pattern in compareValue.
func (*RegexOperator) Evaluate ¶
func (o *RegexOperator) Evaluate(factValue interface{}, compareValue interface{}) (bool, error)
Evaluate checks if factValue matches the regex pattern in compareValue. Both values must be strings. Returns an error if regex evaluation fails.
type Rule ¶
type Rule struct {
Name string `json:"name,omitempty"`
Priority int `json:"priority,omitempty"` // Higher priority rules are evaluated first
Conditions ConditionSet `json:"conditions"`
OnSuccess []RuleEvent `json:"onSuccess,omitempty"` // Events to invoke on success
OnFailure []RuleEvent `json:"onFailure,omitempty"` // Events to invoke on failure
Result bool
}
Rule represents a business rule with conditions and an associated event. Rules are evaluated against facts in an Almanac. When all conditions are met, the rule's event is triggered and any registered callbacks are invoked.
Example:
rule := &gre.Rule{
Name: "adult-user",
Priority: 10,
Conditions: gre.ConditionSet{
All: []gre.ConditionNode{
{Condition: &gre.Condition{
Fact: "age",
Operator: "greater_than",
Value: 18,
}},
},
},
OnSuccess: []RuleEvent{
{Name: "send-welcome-email", Params: map[string]interface{}{"template": "welcome"}},
},
}
func (*Rule) GetRequiredFacts ¶
GetRequiredFacts returns the list of all facts required by this rule.
type RuleBuilder ¶
type RuleBuilder struct {
// contains filtered or unexported fields
}
RuleBuilder provides a fluent API for building rules.
func NewRuleBuilder ¶
func NewRuleBuilder() *RuleBuilder
NewRuleBuilder creates a new RuleBuilder instance.
func (*RuleBuilder) Build ¶
func (rb *RuleBuilder) Build() *Rule
Build returns the constructed Rule.
func (*RuleBuilder) WithConditions ¶
func (rb *RuleBuilder) WithConditions(node ConditionNode) *RuleBuilder
WithConditions sets the conditions for the rule.
func (*RuleBuilder) WithName ¶
func (rb *RuleBuilder) WithName(name string) *RuleBuilder
WithName sets the name of the rule.
func (*RuleBuilder) WithOnFailure ¶
func (rb *RuleBuilder) WithOnFailure(eventNames ...string) *RuleBuilder
WithOnFailure sets the event names for the rule.
func (*RuleBuilder) WithOnFailureEvent ¶
func (rb *RuleBuilder) WithOnFailureEvent(event RuleEvent) *RuleBuilder
WithOnFailureEvent adds a detailed event with parameters to the rule.
func (*RuleBuilder) WithOnSuccess ¶
func (rb *RuleBuilder) WithOnSuccess(eventNames ...string) *RuleBuilder
WithOnSuccess sets the event names for the rule.
func (*RuleBuilder) WithOnSuccessEvent ¶
func (rb *RuleBuilder) WithOnSuccessEvent(event RuleEvent) *RuleBuilder
WithOnSuccessEvent adds a detailed event with parameters to the rule.
func (*RuleBuilder) WithPriority ¶
func (rb *RuleBuilder) WithPriority(priority int) *RuleBuilder
WithPriority sets the priority of the rule.
type RuleEngineError ¶
type RuleEngineError struct {
Type ErrorType // The category of error
Msg string // Human-readable error message
Err error // Wrapped underlying error (optional)
}
RuleEngineError is the base error type for all errors in the rule engine. It categorizes errors by type and optionally wraps underlying errors.
func (*RuleEngineError) Error ¶
func (e *RuleEngineError) Error() string
Error implements the error interface
func (*RuleEngineError) Unwrap ¶
func (e *RuleEngineError) Unwrap() error
Unwrap returns the wrapped error
type RuleError ¶
RuleError represents an error related to a specific rule evaluation or definition.
type RuleEvent ¶
type RuleEvent struct {
Name string `json:"name"`
Params map[string]interface{} `json:"params,omitempty"`
}
RuleEvent represents an event reference within a rule, optionally with parameters.
func (*RuleEvent) UnmarshalJSON ¶
UnmarshalJSON implements custom JSON unmarshaling for RuleEvent. It supports both a simple string (event name) or a full object with parameters.
type RuleProvider ¶
type RuleProvider interface {
// FetchRules retrieves a list of rules from the source.
FetchRules(ctx context.Context) ([]*Rule, error)
}
RuleProvider defines the interface for fetching rules from external sources.
type RuleResult ¶
type RuleResult struct {
Name string `json:"name"`
Priority int `json:"priority"`
Result bool `json:"result"`
Conditions *ConditionSetResult `json:"conditions"`
OnSuccess []RuleEvent `json:"onSuccess,omitempty"`
OnFailure []RuleEvent `json:"onFailure,omitempty"`
}
RuleResult represents the complete evaluation result of a single rule.