Skip to content

Commit 9564ed9

Browse files
authored
feat: Add ability to set Numbers to Fact Pointers (#495)
Add the ability to set a number to a Fact field pointer if the pointer points to a number value.
1 parent 8b016a0 commit 9564ed9

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

examples/NumberToPointer_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package examples
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hyperjumptech/grule-rule-engine/ast"
7+
"github.com/hyperjumptech/grule-rule-engine/builder"
8+
"github.com/hyperjumptech/grule-rule-engine/engine"
9+
"github.com/hyperjumptech/grule-rule-engine/pkg"
10+
"github.com/stretchr/testify/assert"
11+
)
12+
13+
const (
14+
trainRule = `
15+
rule TrainSpeedAdjust "Adjust Train speed based on passenger count" salience 10 {
16+
when
17+
Train.PassengerCount > 50
18+
then
19+
Train.Speed = 75.45;
20+
Train.Stops = Train.Stops - 1;
21+
Retract("TrainSpeedAdjust");
22+
}
23+
`
24+
)
25+
26+
type Train struct {
27+
Speed *float32
28+
PassengerCount *uint16
29+
Stops *int64
30+
}
31+
32+
func TestSetNumberToPointer(t *testing.T) {
33+
34+
speed := float32(204.31)
35+
passengerCount := uint16(100)
36+
stops := int64(3)
37+
train := &Train{
38+
Speed: &speed,
39+
PassengerCount: &passengerCount,
40+
Stops: &stops,
41+
}
42+
43+
dataContext := ast.NewDataContext()
44+
err := dataContext.Add("Train", train)
45+
assert.NoError(t, err)
46+
47+
lib := ast.NewKnowledgeLibrary()
48+
rb := builder.NewRuleBuilder(lib)
49+
err = rb.BuildRuleFromResource("TestSetNumberToPointer", "0.1.1", pkg.NewBytesResource([]byte(trainRule)))
50+
assert.NoError(t, err)
51+
eng := &engine.GruleEngine{MaxCycle: 5}
52+
kb, err := lib.NewKnowledgeBaseInstance("TestSetNumberToPointer", "0.1.1")
53+
assert.NoError(t, err)
54+
err = eng.Execute(dataContext, kb)
55+
assert.NoError(t, err)
56+
57+
assert.Equal(t, int64(2), *train.Stops)
58+
assert.Equal(t, uint16(100), *train.PassengerCount)
59+
assert.Equal(t, float32(75.45), *train.Speed)
60+
}

model/GoDataAccessLayer.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,10 @@ func (node *GoValueNode) SetObjectValueByField(field string, newValue reflect.Va
406406
if pkg.IsNumber(fieldVal) && pkg.IsNumber(newValue) {
407407

408408
return SetNumberValue(fieldVal, newValue)
409+
} else if pkg.IsPointerToNumber(fieldVal) && pkg.IsNumber(newValue) {
410+
return SetNumberValue(fieldVal.Elem(), newValue)
409411
}
412+
410413
fieldVal.Set(newValue)
411414

412415
return nil

pkg/reflectools.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,11 @@ func IsNumber(val reflect.Value) bool {
659659
}
660660
}
661661

662+
// IsPointerToNumber will check a value if it is a pointer to a number eg, int, uint, or float
663+
func IsPointerToNumber(val reflect.Value) bool {
664+
return IsNumber(GetValueElem(val))
665+
}
666+
662667
// GetValueElem will return the value val contains if val is of Kind Interface or Pointer
663668
func GetValueElem(val reflect.Value) reflect.Value {
664669
if val.Kind() == reflect.Pointer || val.Kind() == reflect.Interface {

0 commit comments

Comments
 (0)