@@ -635,15 +635,23 @@ impl<'a, H: Host> AccountResolver<'a, H> {
635
635
Ok ( ( ) )
636
636
}
637
637
638
- fn get_targeting_key ( & self , targeting_key : & str ) -> Result < Option < & str > , String > {
638
+ fn get_targeting_key ( & self , targeting_key : & str ) -> Result < Option < String > , String > {
639
639
let unit_value = self . get_attribute_value ( targeting_key) ;
640
640
match & unit_value. kind {
641
641
None => Ok ( None ) ,
642
642
Some ( Kind :: NullValue ( _) ) => Ok ( None ) ,
643
- Some ( Kind :: StringValue ( string_unit) ) => Ok ( Some ( string_unit) ) ,
643
+ Some ( Kind :: StringValue ( string_unit) ) => Ok ( Some ( string_unit. clone ( ) ) ) ,
644
+ Some ( Kind :: NumberValue ( num_value) ) => {
645
+ if num_value. is_finite ( ) && num_value. fract ( ) == 0.0 {
646
+ Ok ( Some ( format ! ( "{:.0}" , num_value) ) )
647
+ } else {
648
+ Err ( "TargetingKeyError" . to_string ( ) )
649
+ }
650
+ }
644
651
_ => Err ( "TargetingKeyError" . to_string ( ) ) ,
645
652
}
646
653
}
654
+
647
655
pub fn resolve_flag_name ( & ' a self , flag_name : & str ) -> Option < ResolvedValue < ' a > > {
648
656
self . state
649
657
. flags
@@ -675,15 +683,13 @@ impl<'a, H: Host> AccountResolver<'a, H> {
675
683
} else {
676
684
TARGETING_KEY
677
685
} ;
678
- let unit_value = self . get_attribute_value ( targeting_key) ;
679
- let unit = match & unit_value. kind {
680
- None => continue ,
681
- Some ( Kind :: NullValue ( _) ) => continue ,
682
- Some ( Kind :: StringValue ( string_unit) ) => string_unit,
683
- _ => return resolved_value. error ( ResolveReason :: TargetingKeyError ) ,
686
+ let unit: String = match self . get_targeting_key ( targeting_key) {
687
+ Ok ( Some ( u) ) => u,
688
+ Ok ( None ) => continue ,
689
+ Err ( _) => return resolved_value. error ( ResolveReason :: TargetingKeyError ) ,
684
690
} ;
685
691
686
- if !self . segment_match ( segment, unit) {
692
+ if !self . segment_match ( segment, & unit) {
687
693
// ResolveReason::SEGMENT_NOT_MATCH
688
694
continue ;
689
695
}
@@ -712,7 +718,7 @@ impl<'a, H: Host> AccountResolver<'a, H> {
712
718
resolved_value. attribute_fallthrough_rule (
713
719
rule,
714
720
& assignment. assignment_id ,
715
- unit,
721
+ & unit,
716
722
) ;
717
723
continue ;
718
724
}
@@ -721,7 +727,7 @@ impl<'a, H: Host> AccountResolver<'a, H> {
721
727
rule,
722
728
segment,
723
729
& assignment. assignment_id ,
724
- unit,
730
+ & unit,
725
731
)
726
732
}
727
733
rule:: assignment:: Assignment :: Variant (
@@ -739,7 +745,7 @@ impl<'a, H: Host> AccountResolver<'a, H> {
739
745
segment,
740
746
variant,
741
747
& assignment. assignment_id ,
742
- unit,
748
+ & unit,
743
749
) ;
744
750
}
745
751
} ;
@@ -1591,6 +1597,51 @@ mod tests {
1591
1597
}
1592
1598
}
1593
1599
1600
+ #[ test]
1601
+ fn test_targeting_key_integer_supported ( ) {
1602
+ let state =
1603
+ ResolverState :: from_proto ( EXAMPLE_STATE . to_owned ( ) . into ( ) , "confidence-demo-june" ) ;
1604
+
1605
+ // Using integer for visitor_id should be treated as string and work
1606
+ let context_json = r#"{"visitor_id": 26}"# ;
1607
+ let resolver: AccountResolver < ' _ , L > = state
1608
+ . get_resolver_with_json_context ( SECRET , context_json, & ENCRYPTION_KEY )
1609
+ . unwrap ( ) ;
1610
+
1611
+ let flag = resolver
1612
+ . state
1613
+ . flags
1614
+ . get ( "flags/fallthrough-test-2" )
1615
+ . unwrap ( ) ;
1616
+ let resolved_value = resolver. resolve_flag ( flag) ;
1617
+
1618
+ assert_eq ! ( resolved_value. reason as i32 , ResolveReason :: Match as i32 ) ;
1619
+ let assignment_match = resolved_value. assignment_match . unwrap ( ) ;
1620
+ assert_eq ! ( assignment_match. targeting_key, "26" ) ;
1621
+ }
1622
+
1623
+ #[ test]
1624
+ fn test_targeting_key_fractional_rejected ( ) {
1625
+ let state =
1626
+ ResolverState :: from_proto ( EXAMPLE_STATE . to_owned ( ) . into ( ) , "confidence-demo-june" ) ;
1627
+
1628
+ // Fractional number for visitor_id should be rejected
1629
+ let context_json = r#"{"visitor_id": 26.5}"# ;
1630
+ let resolver: AccountResolver < ' _ , L > = state
1631
+ . get_resolver_with_json_context ( SECRET , context_json, & ENCRYPTION_KEY )
1632
+ . unwrap ( ) ;
1633
+
1634
+ let flag = resolver
1635
+ . state
1636
+ . flags
1637
+ . get ( "flags/fallthrough-test-2" )
1638
+ . unwrap ( ) ;
1639
+ let resolved_value = resolver. resolve_flag ( flag) ;
1640
+
1641
+ assert_eq ! ( resolved_value. reason as i32 , ResolveReason :: TargetingKeyError as i32 ) ;
1642
+ assert ! ( resolved_value. assignment_match. is_none( ) ) ;
1643
+ }
1644
+
1594
1645
// eq rules
1595
1646
1596
1647
#[ test]
0 commit comments