@@ -63,6 +63,7 @@ pub enum ConstraintExpression {
63
63
#[ cfg_attr( feature = "strict" , serde( deny_unknown_fields) ) ]
64
64
pub struct Variant {
65
65
pub name : String ,
66
+ #[ serde( deserialize_with = "deserialize_number_from_string" ) ]
66
67
pub weight : u16 ,
67
68
pub payload : Option < HashMap < String , String > > ,
68
69
pub overrides : Option < Vec < VariantOverride > > ,
@@ -137,6 +138,25 @@ pub struct MetricsBucket {
137
138
pub toggles : HashMap < String , ToggleMetrics > ,
138
139
}
139
140
141
+ fn deserialize_number_from_string < ' de , T , D > ( deserializer : D ) -> Result < T , D :: Error >
142
+ where
143
+ D : serde:: Deserializer < ' de > ,
144
+ T : std:: str:: FromStr + serde:: Deserialize < ' de > ,
145
+ <T as std:: str:: FromStr >:: Err : std:: fmt:: Display ,
146
+ {
147
+ #[ derive( Deserialize ) ]
148
+ #[ serde( untagged) ]
149
+ enum StringOrInt < T > {
150
+ String ( String ) ,
151
+ Number ( T ) ,
152
+ }
153
+
154
+ match StringOrInt :: < T > :: deserialize ( deserializer) ? {
155
+ StringOrInt :: String ( s) => s. parse :: < T > ( ) . map_err ( serde:: de:: Error :: custom) ,
156
+ StringOrInt :: Number ( i) => Ok ( i) ,
157
+ }
158
+ }
159
+
140
160
#[ cfg( test) ]
141
161
mod tests {
142
162
use super :: Registration ;
@@ -249,6 +269,16 @@ mod tests {
249
269
Ok ( ( ) )
250
270
}
251
271
272
+ #[ test]
273
+ fn test_parse_variant_with_str_weight ( ) -> Result < ( ) , serde_json:: Error > {
274
+ let data = r#"
275
+ {"name":"Foo","weight":"50","payload":{"type":"string","value":"bar"}}
276
+ "# ;
277
+ let parsed: super :: Variant = serde_json:: from_str ( data) ?;
278
+ assert_eq ! ( 50 , parsed. weight) ;
279
+ Ok ( ( ) )
280
+ }
281
+
252
282
#[ test]
253
283
fn test_registration_customisation ( ) {
254
284
Registration {
0 commit comments