-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Andrey Leybovich
committed
Apr 29, 2024
0 parents
commit 00d67dc
Showing
10 changed files
with
720 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"name": "Launch Package", | ||
"type": "go", | ||
"request": "launch", | ||
"mode": "auto", | ||
"program": "${fileDirname}" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/dop251/goja" | ||
) | ||
|
||
type Condition struct { | ||
Name string `yaml:"name"` | ||
Description string `yaml:"description"` | ||
Check string `yaml:"check"` | ||
True *struct { | ||
Description string `yaml:"description"` | ||
Action string `yaml:"action"` | ||
Next string `yaml:"next"` | ||
Terminate bool `yaml:"terminate"` | ||
} `yaml:"true"` | ||
False *struct { | ||
Description string `yaml:"description"` | ||
Action string `yaml:"action"` | ||
Next string `yaml:"next"` | ||
Terminate bool `yaml:"terminate"` | ||
} `yaml:"false"` | ||
} | ||
|
||
// Run the conditions recursively | ||
func (rr *RulesRunner[Context]) runCondition(vm *goja.Runtime, rules *Rules, condition *Condition) error { | ||
fmt.Print("Running condition: ", condition.Name, "\n") | ||
|
||
// Evaluate the check function | ||
checkFunc, ok := goja.AssertFunction(vm.Get(condition.Name)) | ||
if !ok { | ||
return fmt.Errorf("check function not found: %s", condition.Name) | ||
} | ||
checkResult, err := checkFunc(goja.Undefined()) | ||
if err != nil { | ||
return fmt.Errorf("error evaluating check function %s: %v", condition.Name, err) | ||
} | ||
|
||
if checkResult.ToBoolean() { // If check was true | ||
if condition.True != nil { | ||
fmt.Print("\tRunning TRUE check: ", condition.True.Description, "\n") | ||
if condition.True.Action != "" { | ||
// Run the action function | ||
actionFuncName := condition.Name + "_true" | ||
fmt.Print("\t\tRunning action function: ", actionFuncName, "\n") | ||
actionFunc, ok := goja.AssertFunction(vm.Get(actionFuncName)) | ||
if !ok { | ||
return fmt.Errorf("action function not found: %s", actionFuncName) | ||
} | ||
_, err := actionFunc(goja.Undefined()) | ||
if err != nil { | ||
return fmt.Errorf("error running action function: %v", err) | ||
} | ||
} | ||
if condition.True.Next != "" { | ||
nextCondition, err := findConditionByName(rules, condition.True.Next) | ||
if err != nil { | ||
return fmt.Errorf("unexpected error: condition '%s' not found", condition.True.Next) | ||
} | ||
err = rr.runCondition(vm, rules, nextCondition) | ||
if err != nil { | ||
return fmt.Errorf("error while running condition '%s': %v", condition.True.Next, err) | ||
} | ||
} | ||
if condition.True.Terminate { | ||
fmt.Print("Terminating\n") | ||
return nil | ||
} | ||
} | ||
} else { // if check was false | ||
if condition.False != nil { | ||
fmt.Print("\tRunning FALSE check: ", condition.False.Description, "\n") | ||
if condition.False.Action != "" { | ||
// Run the action function | ||
actionFuncName := condition.Name + "_false" | ||
fmt.Print("\t\tRunning action function: ", actionFuncName, "\n") | ||
actionFunc, ok := goja.AssertFunction(vm.Get(actionFuncName)) | ||
if !ok { | ||
return fmt.Errorf("action function not found: %s", actionFuncName) | ||
} | ||
_, err := actionFunc(goja.Undefined()) | ||
if err != nil { | ||
return fmt.Errorf("error running action function: %v", err) | ||
} | ||
} | ||
if condition.False.Next != "" { | ||
nextCondition, err := findConditionByName(rules, condition.False.Next) | ||
if err != nil { | ||
return fmt.Errorf("unexpected error: condition '%s' not found", condition.False.Next) | ||
} | ||
|
||
err = rr.runCondition(vm, rules, nextCondition) | ||
if err != nil { | ||
return fmt.Errorf("error while running condition '%s': %v", condition.False.Next, err) | ||
} | ||
} | ||
if condition.False.Terminate { | ||
fmt.Print("Terminating\n") | ||
return nil | ||
} | ||
} | ||
} | ||
|
||
return nil // return from runCondition | ||
} | ||
|
||
func findConditionByName(rule *Rules, name string) (*Condition, error) { | ||
for _, condition := range rule.Conditions { | ||
if condition.Name == name { | ||
return &condition, nil | ||
} | ||
} | ||
return nil, fmt.Errorf("Condition not found: %s", name) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
module yabre | ||
|
||
go 1.22.2 | ||
|
||
require ( | ||
github.com/dop251/goja v0.0.0-20240220182346-e401ed450204 | ||
gopkg.in/yaml.v2 v2.4.0 | ||
) | ||
|
||
require ( | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/dlclark/regexp2 v1.7.0 // indirect | ||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect | ||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
github.com/stretchr/testify v1.9.0 // indirect | ||
golang.org/x/text v0.3.8 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= | ||
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= | ||
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= | ||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= | ||
github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= | ||
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= | ||
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= | ||
github.com/dop251/goja v0.0.0-20240220182346-e401ed450204 h1:O7I1iuzEA7SG+dK8ocOBSlYAA9jBUmCYl/Qa7ey7JAM= | ||
github.com/dop251/goja v0.0.0-20240220182346-e401ed450204/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= | ||
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= | ||
github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= | ||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= | ||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= | ||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= | ||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= | ||
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= | ||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | ||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | ||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= | ||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= | ||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= | ||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= | ||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= | ||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= | ||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | ||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= | ||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | ||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= | ||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | ||
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= | ||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= | ||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= | ||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= | ||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= | ||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= | ||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= | ||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/dop251/goja" | ||
"gopkg.in/yaml.v2" | ||
) | ||
|
||
type Rules struct { | ||
Conditions map[string]Condition `yaml:"conditions"` | ||
} | ||
|
||
func (rr *RulesRunner[Context]) RunRules(context *Context, startCondition string) (*Context, error) { | ||
rules := rr.Rules | ||
vm := goja.New() | ||
|
||
// Add context to vm | ||
vm.Set("context", *context) | ||
|
||
// Add debug function to vm | ||
if rr.DebugCallback != nil { | ||
vm.Set("debug", rr.DebugCallback) | ||
} | ||
|
||
// Add go functions to vm | ||
if rr.GoFunctions != nil { | ||
for name, f := range rr.GoFunctions { | ||
vm.Set(name, f) | ||
} | ||
} | ||
|
||
// Add all js functions to the vm | ||
err := rr.addJsFunctions(vm) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Start running the conditions from the first condition | ||
condition, err := findConditionByName(rules, startCondition) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Start running the conditions from the first condition | ||
err = rr.runCondition(vm, rules, condition) | ||
|
||
// Get the updated context | ||
*context = vm.Get("context").ToObject(vm).Export().(Context) | ||
|
||
return context, err | ||
} | ||
|
||
func (rr *RulesRunner[Context]) loadRulesFromYaml(fileName string) (*Rules, error) { | ||
yamlFile, err := os.ReadFile(fileName) | ||
if err != nil { | ||
return nil, fmt.Errorf("error reading YAML file: %v", err) | ||
} | ||
|
||
// Parse the YAML into a Rule struct | ||
var rules Rules | ||
err = yaml.Unmarshal(yamlFile, &rules) | ||
if err != nil { | ||
return nil, fmt.Errorf("error parsing YAML: %v", err) | ||
} | ||
|
||
// add names to conditions from the Rule map | ||
for name, condition := range rules.Conditions { | ||
condition.Name = name | ||
rules.Conditions[name] = condition | ||
} | ||
|
||
return &rules, nil | ||
} | ||
|
||
func (rr *RulesRunner[Context]) addJsFunctions(vm *goja.Runtime) error { | ||
// add all js functions to the vm | ||
for _, condition := range rr.Rules.Conditions { | ||
if condition.Check != "" { | ||
_, err := vm.RunString(condition.Check) | ||
if err != nil { | ||
return fmt.Errorf("error injecting check function into vm: %v", err) | ||
} | ||
} | ||
if condition.True != nil && condition.True.Action != "" { | ||
_, err := vm.RunString(condition.True.Action) | ||
if err != nil { | ||
return fmt.Errorf("error injecting action function into vm: %v", err) | ||
} | ||
} | ||
if condition.False != nil && condition.False.Action != "" { | ||
_, err := vm.RunString(condition.False.Action) | ||
if err != nil { | ||
return fmt.Errorf("error injecting action function into vm: %v", err) | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package main | ||
|
||
type RulesRunner[Context interface{}] struct { | ||
Rules *Rules | ||
Context *Context | ||
DebugCallback func(Context, interface{}) | ||
GoFunctions map[string]func(...interface{}) (interface{}, error) | ||
} | ||
|
||
type WithOption[Context interface{}] func(*RulesRunner[Context]) | ||
|
||
// WithDebugCallback sets the DebugCallback option | ||
func WithDebugCallback[Context interface{}](callback func(Context, interface{})) WithOption[Context] { | ||
return func(runner *RulesRunner[Context]) { | ||
runner.DebugCallback = callback | ||
} | ||
} | ||
|
||
func WithGoFunction[Context interface{}](name string, f func(...interface{}) (interface{}, error)) WithOption[Context] { | ||
return func(runner *RulesRunner[Context]) { | ||
if runner.GoFunctions == nil { | ||
runner.GoFunctions = make(map[string]func(...interface{}) (interface{}, error)) | ||
} | ||
runner.GoFunctions[name] = f | ||
} | ||
} | ||
|
||
func NewRulesRunnerFromYaml[Context interface{}](fileName string, context *Context, options ...WithOption[Context]) (*RulesRunner[Context], error) { | ||
rr := &RulesRunner[Context]{Context: context} | ||
|
||
// Execute options | ||
for _, op := range options { | ||
op(rr) | ||
} | ||
|
||
// Load the rules from the YAML file | ||
rules, err := rr.loadRulesFromYaml(fileName) | ||
if err != nil { | ||
return nil, err | ||
} | ||
rr.Rules = rules | ||
|
||
return rr, nil | ||
} |
Oops, something went wrong.