@@ -9,8 +9,14 @@ import (
99)
1010
1111type 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+ }
1420}
1521
1622type flagConfiguration struct {
@@ -20,17 +26,39 @@ type flagConfiguration struct {
2026 Variations map [string ]variation `json:"variations"`
2127 Allocations []allocation `json:"allocations"`
2228 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 () {
2641 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+ }
2851 }
2952}
3053
3154type 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 {}
3462}
3563
3664type variationType int
@@ -84,33 +112,52 @@ func (v *variationType) UnmarshalJSON(data []byte) error {
84112 return nil
85113}
86114
87- func (ty variationType ) valueToAssignmentValue (value interface {} ) (interface {}, error ) {
115+ func (ty variationType ) parseVariationValue (value json. RawMessage ) (interface {}, error ) {
88116 switch ty {
89117 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+ }
91123 return s , nil
92124 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
99129 }
130+ return i , nil
100131 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
103138 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
106145 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 )
110148 if err != nil {
111149 return nil , err
112150 }
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
114161 default :
115162 return nil , fmt .Errorf ("unexpected variation type: %v" , ty )
116163 }
@@ -125,19 +172,19 @@ type allocation struct {
125172 DoLog * bool `json:"doLog"`
126173}
127174
128- func (a * allocation ) Precompute () {
175+ func (a * allocation ) precompute () {
129176 for i := range a .Rules {
130- a .Rules [i ].Precompute ()
177+ a .Rules [i ].precompute ()
131178 }
132179}
133180
134181type rule struct {
135182 Conditions []condition `json:"conditions"`
136183}
137184
138- func (r * rule ) Precompute () {
185+ func (r * rule ) precompute () {
139186 for i := range r .Conditions {
140- r .Conditions [i ].Precompute ()
187+ r .Conditions [i ].precompute ()
141188 }
142189}
143190
@@ -152,7 +199,7 @@ type condition struct {
152199 SemVerValueValid bool
153200}
154201
155- func (c * condition ) Precompute () {
202+ func (c * condition ) precompute () {
156203 // Try to convert Value to a float64
157204 if num , err := toFloat64 (c .Value ); err == nil {
158205 c .NumericValue = num
0 commit comments