46 lines
883 B
Go
46 lines
883 B
Go
|
package rule
|
||
|
|
||
|
import (
|
||
|
"github.com/expr-lang/expr"
|
||
|
"github.com/expr-lang/expr/vm"
|
||
|
"github.com/pkg/errors"
|
||
|
)
|
||
|
|
||
|
type Engine[E any] struct {
|
||
|
rules []*vm.Program
|
||
|
}
|
||
|
|
||
|
func (e *Engine[E]) Apply(env E) ([]any, error) {
|
||
|
results := make([]any, 0, len(e.rules))
|
||
|
for i, r := range e.rules {
|
||
|
result, err := expr.Run(r, env)
|
||
|
if err != nil {
|
||
|
return nil, errors.Wrapf(err, "could not run rule #%d", i)
|
||
|
}
|
||
|
|
||
|
results = append(results, result)
|
||
|
}
|
||
|
|
||
|
return results, nil
|
||
|
}
|
||
|
|
||
|
func NewEngine[E any](funcs ...OptionFunc) (*Engine[E], error) {
|
||
|
opts := NewOptions(funcs...)
|
||
|
|
||
|
engine := &Engine[E]{
|
||
|
rules: make([]*vm.Program, 0, len(opts.Rules)),
|
||
|
}
|
||
|
|
||
|
for i, r := range opts.Rules {
|
||
|
|
||
|
program, err := expr.Compile(r, opts.Expr...)
|
||
|
if err != nil {
|
||
|
return nil, errors.Wrapf(err, "could not compile rule #%d", i)
|
||
|
}
|
||
|
|
||
|
engine.rules = append(engine.rules, program)
|
||
|
}
|
||
|
|
||
|
return engine, nil
|
||
|
}
|