@@ -9,8 +9,14 @@ import (
9
9
)
10
10
11
11
type configResponse struct {
12
- Flags map [string ]flagConfiguration `json:"flags"`
13
- Bandits map [string ][]banditVariation `json:"bandits,omitempty"`
12
+ Flags map [string ]* flagConfiguration `json:"flags"`
13
+ Bandits map [string ][]banditVariation `json:"bandits,omitempty"`
14
+ }
15
+
16
+ func (response * configResponse ) precompute () {
17
+ for i := range response .Flags {
18
+ response .Flags [i ].precompute ()
19
+ }
14
20
}
15
21
16
22
type flagConfiguration struct {
@@ -20,17 +26,39 @@ type flagConfiguration struct {
20
26
Variations map [string ]variation `json:"variations"`
21
27
Allocations []allocation `json:"allocations"`
22
28
TotalShards int64 `json:"totalShards"`
23
- }
24
-
25
- func (flag * flagConfiguration ) Precompute () {
29
+ // Cached Variations parsed according to `VariationType`.
30
+ //
31
+ // Types are as follows:
32
+ // - STRING -> string
33
+ // - NUMERIC -> float64
34
+ // - INTEGER -> int64
35
+ // - BOOLEAN -> bool
36
+ // - JSON -> jsonVariationValue
37
+ ParsedVariations map [string ]interface {} `json:"-"`
38
+ }
39
+
40
+ func (flag * flagConfiguration ) precompute () {
26
41
for i := range flag .Allocations {
27
- flag .Allocations [i ].Precompute ()
42
+ flag .Allocations [i ].precompute ()
43
+ }
44
+
45
+ flag .ParsedVariations = make (map [string ]interface {}, len (flag .Variations ))
46
+ for i := range flag .Variations {
47
+ value , err := flag .VariationType .parseVariationValue (flag .Variations [i ].Value )
48
+ if err == nil {
49
+ flag .ParsedVariations [i ] = value
50
+ }
28
51
}
29
52
}
30
53
31
54
type variation struct {
32
- Key string `json:"key"`
33
- Value interface {} `json:"value"`
55
+ Key string `json:"key"`
56
+ Value json.RawMessage `json:"value"`
57
+ }
58
+
59
+ type jsonVariationValue struct {
60
+ Raw []byte
61
+ Parsed interface {}
34
62
}
35
63
36
64
type variationType int
@@ -84,33 +112,52 @@ func (v *variationType) UnmarshalJSON(data []byte) error {
84
112
return nil
85
113
}
86
114
87
- func (ty variationType ) valueToAssignmentValue (value interface {} ) (interface {}, error ) {
115
+ func (ty variationType ) parseVariationValue (value json. RawMessage ) (interface {}, error ) {
88
116
switch ty {
89
117
case stringVariation :
90
- s := value .(string )
118
+ var s string
119
+ err := json .Unmarshal (value , & s )
120
+ if err != nil {
121
+ return nil , err
122
+ }
91
123
return s , nil
92
124
case integerVariation :
93
- f64 := value .(float64 )
94
- i64 := int64 (f64 )
95
- if f64 == float64 (i64 ) {
96
- return i64 , nil
97
- } else {
98
- return nil , fmt .Errorf ("failed to convert number to integer" )
125
+ var i int64
126
+ err := json .Unmarshal (value , & i )
127
+ if err != nil {
128
+ return nil , err
99
129
}
130
+ return i , nil
100
131
case numericVariation :
101
- number := value .(float64 )
102
- return number , nil
132
+ var f float64
133
+ err := json .Unmarshal (value , & f )
134
+ if err != nil {
135
+ return nil , err
136
+ }
137
+ return f , nil
103
138
case booleanVariation :
104
- v := value .(bool )
105
- return v , nil
139
+ var b bool
140
+ err := json .Unmarshal (value , & b )
141
+ if err != nil {
142
+ return nil , err
143
+ }
144
+ return b , nil
106
145
case jsonVariation :
107
- v := value .(string )
108
- var result interface {}
109
- err := json .Unmarshal ([]byte (v ), & result )
146
+ var s string
147
+ err := json .Unmarshal (value , & s )
110
148
if err != nil {
111
149
return nil , err
112
150
}
113
- return result , nil
151
+
152
+ raw := []byte (s )
153
+
154
+ var parsed interface {}
155
+ err = json .Unmarshal (raw , & parsed )
156
+ if err != nil {
157
+ return nil , err
158
+ }
159
+
160
+ return jsonVariationValue {raw , parsed }, nil
114
161
default :
115
162
return nil , fmt .Errorf ("unexpected variation type: %v" , ty )
116
163
}
@@ -125,19 +172,19 @@ type allocation struct {
125
172
DoLog * bool `json:"doLog"`
126
173
}
127
174
128
- func (a * allocation ) Precompute () {
175
+ func (a * allocation ) precompute () {
129
176
for i := range a .Rules {
130
- a .Rules [i ].Precompute ()
177
+ a .Rules [i ].precompute ()
131
178
}
132
179
}
133
180
134
181
type rule struct {
135
182
Conditions []condition `json:"conditions"`
136
183
}
137
184
138
- func (r * rule ) Precompute () {
185
+ func (r * rule ) precompute () {
139
186
for i := range r .Conditions {
140
- r .Conditions [i ].Precompute ()
187
+ r .Conditions [i ].precompute ()
141
188
}
142
189
}
143
190
@@ -152,7 +199,7 @@ type condition struct {
152
199
SemVerValueValid bool
153
200
}
154
201
155
- func (c * condition ) Precompute () {
202
+ func (c * condition ) precompute () {
156
203
// Try to convert Value to a float64
157
204
if num , err := toFloat64 (c .Value ); err == nil {
158
205
c .NumericValue = num
0 commit comments