@@ -21,7 +21,7 @@ import (
21
21
"errors"
22
22
"reflect"
23
23
24
- "github.com/json-iterator/go"
24
+ jsoniter "github.com/json-iterator/go"
25
25
"github.com/optimizely/go-sdk/pkg/entities"
26
26
)
27
27
@@ -31,21 +31,16 @@ var json = jsoniter.ConfigCompatibleWithStandardLibrary
31
31
// Takes the conditions array from the audience in the datafile and turns it into a condition tree
32
32
func buildConditionTree (conditions interface {}) (conditionTree * entities.TreeNode , retErr error ) {
33
33
34
- var parsedConditions interface {}
35
- switch v := conditions .(type ) {
36
- case string :
37
- if err := json .Unmarshal ([]byte (v ), & parsedConditions ); err != nil {
38
- retErr = err
39
- return
40
- }
41
- default :
42
- parsedConditions = conditions
34
+ parsedConditions , retErr := parseConditions (conditions )
35
+ if retErr != nil {
36
+ return
43
37
}
44
38
45
39
value := reflect .ValueOf (parsedConditions )
46
40
visited := make (map [interface {}]bool )
47
41
48
42
conditionTree = & entities.TreeNode {}
43
+
49
44
var populateConditions func (v reflect.Value , root * entities.TreeNode )
50
45
populateConditions = func (v reflect.Value , root * entities.TreeNode ) {
51
46
@@ -73,17 +68,10 @@ func buildConditionTree(conditions interface{}) (conditionTree *entities.TreeNod
73
68
continue
74
69
75
70
case map [string ]interface {}:
76
- jsonBody , err := json .Marshal (typedV )
77
- if err != nil {
71
+ if err := createLeafCondition (value , n ); err != nil {
78
72
retErr = err
79
73
return
80
74
}
81
- condition := entities.Condition {}
82
- if err := json .Unmarshal (jsonBody , & condition ); err != nil {
83
- retErr = err
84
- return
85
- }
86
- n .Item = condition
87
75
}
88
76
89
77
root .Nodes = append (root .Nodes , n )
@@ -93,22 +81,64 @@ func buildConditionTree(conditions interface{}) (conditionTree *entities.TreeNod
93
81
}
94
82
}
95
83
96
- populateConditions (value , conditionTree )
84
+ // Check for leaf conditions
85
+ if value .Kind () == reflect .Map {
86
+ typedV := value .Interface ()
87
+ if v , ok := typedV .(map [string ]interface {}); ok {
88
+ n := & entities.TreeNode {}
89
+ if err := createLeafCondition (v , n ); err != nil {
90
+ retErr = err
91
+ return
92
+ }
93
+ conditionTree .Operator = "or"
94
+ conditionTree .Nodes = append (conditionTree .Nodes , n )
95
+ }
96
+ } else {
97
+ populateConditions (value , conditionTree )
98
+ }
99
+
97
100
if conditionTree .Nodes == nil && conditionTree .Operator == "" {
98
101
retErr = errEmptyTree
99
102
conditionTree = nil
100
103
}
101
104
return conditionTree , retErr
102
105
}
103
106
107
+ // Parses conditions for audience in the datafile
108
+ func parseConditions (conditions interface {}) (parsedConditions interface {}, retErr error ) {
109
+ switch v := conditions .(type ) {
110
+ case string :
111
+ if err := json .Unmarshal ([]byte (v ), & parsedConditions ); err != nil {
112
+ return nil , err
113
+ }
114
+ default :
115
+ parsedConditions = conditions
116
+ }
117
+ return parsedConditions , nil
118
+ }
119
+
120
+ // Creates condition for the leaf node in the condition tree
121
+ func createLeafCondition (typedV map [string ]interface {}, node * entities.TreeNode ) error {
122
+ jsonBody , err := json .Marshal (typedV )
123
+ if err != nil {
124
+ return err
125
+ }
126
+ condition := entities.Condition {}
127
+ if err := json .Unmarshal (jsonBody , & condition ); err != nil {
128
+ return err
129
+ }
130
+ node .Item = condition
131
+ return nil
132
+ }
133
+
104
134
// Takes the conditions array from the audience in the datafile and turns it into a condition tree
105
135
func buildAudienceConditionTree (conditions interface {}) (conditionTree * entities.TreeNode , err error ) {
106
136
107
137
var operators = []string {"or" , "and" , "not" } // any other operators?
108
138
value := reflect .ValueOf (conditions )
109
139
visited := make (map [interface {}]bool )
110
140
111
- conditionTree = & entities.TreeNode { Operator : "or" }
141
+ conditionTree = & entities.TreeNode {Operator : "or" }
112
142
var populateConditions func (v reflect.Value , root * entities.TreeNode )
113
143
populateConditions = func (v reflect.Value , root * entities.TreeNode ) {
114
144
0 commit comments