@@ -356,7 +356,7 @@ func (e *evaluator) eval(user User, spec configSpec, depth int, context StatsigC
356356 reason := e .store .initReason
357357 e .store .mu .RUnlock ()
358358 evalDetails := e .createEvaluationDetails (reason )
359- isDynamicConfig := strings .ToLower (spec .Type ) == dynamicConfigType
359+ isDynamicConfig := strings .EqualFold (spec .Type , dynamicConfigType )
360360 if isDynamicConfig {
361361 configValue = spec .DefaultValueJSON
362362 }
@@ -447,7 +447,7 @@ func evalPassPercent(user User, rule configRule, spec configSpec) bool {
447447}
448448
449449func getUnitID (user User , idType string ) string {
450- if idType != "" && strings .ToLower (idType ) != "userid" {
450+ if idType != "" && ! strings .EqualFold (idType , "userid" ) {
451451 if val , ok := user .CustomIDs [idType ]; ok {
452452 return val
453453 }
@@ -478,12 +478,13 @@ func (e *evaluator) evalRule(user User, rule configRule, depth int, context Stat
478478
479479func (e * evaluator ) evalCondition (user User , cond configCondition , depth int , context StatsigContext ) * evalResult {
480480 var value interface {}
481- condType := strings . ToLower ( cond .Type )
482- op := strings . ToLower ( cond .Operator )
483- switch condType {
484- case "public" :
481+ condType := cond .Type
482+ op := cond .Operator
483+ switch {
484+ case strings . EqualFold ( condType , "public" ) :
485485 return & evalResult {Value : true }
486- case "fail_gate" , "pass_gate" :
486+
487+ case strings .EqualFold (condType , "fail_gate" ) || strings .EqualFold (condType , "pass_gate" ):
487488 dependentGateName , ok := cond .TargetValue .(string )
488489 if ! ok {
489490 return & evalResult {Value : false }
@@ -502,105 +503,105 @@ func (e *evaluator) evalCondition(user User, cond configCondition, depth int, co
502503 allExposures = append (result .SecondaryExposures , newExposure )
503504 }
504505
505- if condType == "pass_gate" {
506+ if strings . EqualFold ( condType , "pass_gate" ) {
506507 return & evalResult {Value : result .Value , SecondaryExposures : allExposures }
507508 } else {
508509 return & evalResult {Value : ! result .Value , SecondaryExposures : allExposures }
509510 }
510- case "ip_based" :
511+ case strings . EqualFold ( condType , "ip_based" ) :
511512 value = getFromUser (user , cond .Field )
512513 if value == nil || value == "" {
513514 value = getFromIP (user , cond .Field , e .countryLookup )
514515 }
515- case "ua_based" :
516+ case strings . EqualFold ( condType , "ua_based" ) :
516517 value = getFromUser (user , cond .Field )
517518 if value == nil || value == "" {
518519 value = getFromUserAgent (user , cond .Field , e .uaParser )
519520 }
520- case "user_field" :
521+ case strings . EqualFold ( condType , "user_field" ) :
521522 value = getFromUser (user , cond .Field )
522- case "environment_field" :
523+ case strings . EqualFold ( condType , "environment_field" ) :
523524 value = getFromEnvironment (user , cond .Field )
524- case "current_time" :
525+ case strings . EqualFold ( condType , "current_time" ) :
525526 value = time .Now ().Unix () // time in seconds
526- case "user_bucket" :
527+ case strings . EqualFold ( condType , "user_bucket" ) :
527528 if salt , ok := cond .AdditionalValues ["salt" ]; ok {
528529 value = int64 (getHashUint64Encoding (fmt .Sprintf ("%s.%s" , salt , getUnitID (user , cond .IDType ))) % 1000 )
529530 }
530- case "unit_id" :
531+ case strings . EqualFold ( condType , "unit_id" ) :
531532 value = getUnitID (user , cond .IDType )
532533 default :
533534 return & evalResult {FetchFromServer : true }
534535 }
535536
536537 pass := false
537538 server := false
538- switch op {
539- case "gt" :
539+ switch {
540+ case strings . EqualFold ( op , "gt" ) :
540541 pass = compareNumbers (value , cond .TargetValue , func (x , y float64 ) bool { return x > y })
541- case "gte" :
542+ case strings . EqualFold ( op , "gte" ) :
542543 pass = compareNumbers (value , cond .TargetValue , func (x , y float64 ) bool { return x >= y })
543- case "lt" :
544+ case strings . EqualFold ( op , "lt" ) :
544545 pass = compareNumbers (value , cond .TargetValue , func (x , y float64 ) bool { return x < y })
545- case "lte" :
546+ case strings . EqualFold ( op , "lte" ) :
546547 pass = compareNumbers (value , cond .TargetValue , func (x , y float64 ) bool { return x <= y })
547- case "version_gt" :
548+ case strings . EqualFold ( op , "version_gt" ) :
548549 pass = compareVersions (value , cond .TargetValue , func (x , y []int64 ) bool { return compareVersionsHelper (x , y ) > 0 })
549- case "version_gte" :
550+ case strings . EqualFold ( op , "version_gte" ) :
550551 pass = compareVersions (value , cond .TargetValue , func (x , y []int64 ) bool { return compareVersionsHelper (x , y ) >= 0 })
551- case "version_lt" :
552+ case strings . EqualFold ( op , "version_lt" ) :
552553 pass = compareVersions (value , cond .TargetValue , func (x , y []int64 ) bool { return compareVersionsHelper (x , y ) < 0 })
553- case "version_lte" :
554+ case strings . EqualFold ( op , "version_lte" ) :
554555 pass = compareVersions (value , cond .TargetValue , func (x , y []int64 ) bool { return compareVersionsHelper (x , y ) <= 0 })
555- case "version_eq" :
556+ case strings . EqualFold ( op , "version_eq" ) :
556557 pass = compareVersions (value , cond .TargetValue , func (x , y []int64 ) bool { return compareVersionsHelper (x , y ) == 0 })
557- case "version_neq" :
558+ case strings . EqualFold ( op , "version_neq" ) :
558559 pass = compareVersions (value , cond .TargetValue , func (x , y []int64 ) bool { return compareVersionsHelper (x , y ) != 0 })
559560
560561 // array operations
561- case "any" :
562+ case strings . EqualFold ( op , "any" ) :
562563 pass = arrayAny (cond .TargetValue , value , func (x , y interface {}) bool {
563564 if cond .UserBucket != nil {
564565 return lookupUserBucket (value , cond .UserBucket )
565566 } else {
566- return compareStrings (x , y , true , func (s1 , s2 string ) bool { return s1 == s2 })
567+ return compareStrings (x , y , false , func (s1 , s2 string ) bool { return strings . EqualFold ( s1 , s2 ) })
567568 }
568569 })
569- case "none" :
570+ case strings . EqualFold ( op , "none" ) :
570571 pass = ! arrayAny (cond .TargetValue , value , func (x , y interface {}) bool {
571572 if cond .UserBucket != nil {
572573 return lookupUserBucket (value , cond .UserBucket )
573574 } else {
574- return compareStrings (x , y , true , func (s1 , s2 string ) bool { return s1 == s2 })
575+ return compareStrings (x , y , false , func (s1 , s2 string ) bool { return strings . EqualFold ( s1 , s2 ) })
575576 }
576577 })
577- case "any_case_sensitive" :
578+ case strings . EqualFold ( op , "any_case_sensitive" ) :
578579 pass = arrayAny (cond .TargetValue , value , func (x , y interface {}) bool {
579580 return compareStrings (x , y , false , func (s1 , s2 string ) bool { return s1 == s2 })
580581 })
581- case "none_case_sensitive" :
582+ case strings . EqualFold ( op , "none_case_sensitive" ) :
582583 pass = ! arrayAny (cond .TargetValue , value , func (x , y interface {}) bool {
583584 return compareStrings (x , y , false , func (s1 , s2 string ) bool { return s1 == s2 })
584585 })
585586
586587 // string operations
587- case "str_starts_with_any" :
588+ case strings . EqualFold ( op , "str_starts_with_any" ) :
588589 pass = arrayAny (cond .TargetValue , value , func (x , y interface {}) bool {
589590 return compareStrings (x , y , true , func (s1 , s2 string ) bool { return strings .HasPrefix (s1 , s2 ) })
590591 })
591- case "str_ends_with_any" :
592+ case strings . EqualFold ( op , "str_ends_with_any" ) :
592593 pass = arrayAny (cond .TargetValue , value , func (x , y interface {}) bool {
593594 return compareStrings (x , y , true , func (s1 , s2 string ) bool { return strings .HasSuffix (s1 , s2 ) })
594595 })
595- case "str_contains_any" :
596+ case strings . EqualFold ( op , "str_contains_any" ) :
596597 pass = arrayAny (cond .TargetValue , value , func (x , y interface {}) bool {
597598 return compareStrings (x , y , true , func (s1 , s2 string ) bool { return strings .Contains (s1 , s2 ) })
598599 })
599- case "str_contains_none" :
600+ case strings . EqualFold ( op , "str_contains_none" ) :
600601 pass = ! arrayAny (cond .TargetValue , value , func (x , y interface {}) bool {
601602 return compareStrings (x , y , true , func (s1 , s2 string ) bool { return strings .Contains (s1 , s2 ) })
602603 })
603- case "str_matches" :
604+ case strings . EqualFold ( op , "str_matches" ) :
604605 if cond .TargetValue == nil || value == nil {
605606 pass = cond .TargetValue == nil && value == nil
606607 } else {
@@ -609,30 +610,30 @@ func (e *evaluator) evalCondition(user User, cond configCondition, depth int, co
609610 }
610611
611612 // strict equality
612- case "eq" , "neq" :
613+ case strings . EqualFold ( op , "eq" ) || strings . EqualFold ( op , "neq" ) :
613614 equal := false
614615 // because certain user values are of string type, which cannot be nil, we should check for both nil and empty string
615616 if cond .TargetValue == nil {
616617 equal = value == nil || value == ""
617618 } else {
618619 equal = reflect .DeepEqual (value , cond .TargetValue )
619620 }
620- if op == "eq" {
621+ if strings . EqualFold ( op , "eq" ) {
621622 pass = equal
622623 } else {
623624 pass = ! equal
624625 }
625626
626627 // time
627- case "before" :
628+ case strings . EqualFold ( op , "before" ) :
628629 pass = getTime (value ).Before (getTime (cond .TargetValue ))
629- case "after" :
630+ case strings . EqualFold ( op , "after" ) :
630631 pass = getTime (value ).After (getTime (cond .TargetValue ))
631- case "on" :
632+ case strings . EqualFold ( op , "on" ) :
632633 y1 , m1 , d1 := getTime (value ).Date ()
633634 y2 , m2 , d2 := getTime (cond .TargetValue ).Date ()
634635 pass = (y1 == y2 && m1 == m2 && d1 == d2 )
635- case "in_segment_list" , "not_in_segment_list" :
636+ case strings . EqualFold ( op , "in_segment_list" ) || strings . EqualFold ( op , "not_in_segment_list" ) :
636637 inlist := false
637638 if reflect .TypeOf (cond .TargetValue ).String () == "string" && reflect .TypeOf (value ).String () == "string" {
638639 list := e .store .getIDList (castToString (cond .TargetValue ))
@@ -641,7 +642,7 @@ func (e *evaluator) evalCondition(user User, cond configCondition, depth int, co
641642 _ , inlist = list .ids .Load (base64 .StdEncoding .EncodeToString (h [:])[:8 ])
642643 }
643644 }
644- if op == "in_segment_list" {
645+ if strings . EqualFold ( op , "in_segment_list" ) {
645646 pass = inlist
646647 } else {
647648 pass = ! inlist
@@ -656,22 +657,22 @@ func (e *evaluator) evalCondition(user User, cond configCondition, depth int, co
656657func getFromUser (user User , field string ) interface {} {
657658 var value interface {}
658659 // 1. Try to get from top level user field first
659- switch strings . ToLower ( field ) {
660- case "userid" , "user_id" :
660+ switch {
661+ case strings . EqualFold ( field , "userid" ) || strings . EqualFold ( field , "user_id" ) :
661662 value = user .UserID
662- case "email" :
663+ case strings . EqualFold ( field , "email" ) :
663664 value = user .Email
664- case "ip" , "ipaddress" , "ip_address" :
665+ case strings . EqualFold ( field , "ip" ) || strings . EqualFold ( field , "ipaddress" ) || strings . EqualFold ( field , "ip_address" ) :
665666 value = user .IpAddress
666- case "useragent" , "user_agent" :
667+ case strings . EqualFold ( field , "useragent" ) || strings . EqualFold ( field , "user_agent" ) :
667668 if user .UserAgent != "" { // UserAgent cannot be empty string
668669 value = user .UserAgent
669670 }
670- case "country" :
671+ case strings . EqualFold ( field , "country" ) :
671672 value = user .Country
672- case "locale" :
673+ case strings . EqualFold ( field , "locale" ) :
673674 value = user .Locale
674- case "appversion" , "app_version" :
675+ case strings . EqualFold ( field , "appversion" ) || strings . EqualFold ( field , "app_version" ) :
675676 value = user .AppVersion
676677 }
677678
@@ -712,21 +713,21 @@ func getFromUserAgent(user User, field string, parser *uaParser) string {
712713 if client == nil {
713714 return ""
714715 }
715- switch strings . ToLower ( field ) {
716- case "os_name" , "osname" :
716+ switch {
717+ case strings . EqualFold ( field , "os_name" ) || strings . EqualFold ( field , "osname" ) :
717718 return client .Os .Family
718- case "os_version" , "osversion" :
719+ case strings . EqualFold ( field , "os_version" ) || strings . EqualFold ( field , "osversion" ) :
719720 return strings .Join (removeEmptyStrings ([]string {client .Os .Major , client .Os .Minor , client .Os .Patch , client .Os .PatchMinor }), "." )
720- case "browser_name" , "browsername" :
721+ case strings . EqualFold ( field , "browser_name" ) || strings . EqualFold ( field , "browsername" ) :
721722 return client .UserAgent .Family
722- case "browser_version" , "browserversion" :
723+ case strings . EqualFold ( field , "browser_version" ) || strings . EqualFold ( field , "browserversion" ) :
723724 return strings .Join (removeEmptyStrings ([]string {client .UserAgent .Major , client .UserAgent .Minor , client .UserAgent .Patch }), "." )
724725 }
725726 return ""
726727}
727728
728729func getFromIP (user User , field string , lookup * countryLookup ) string {
729- if strings .ToLower (field ) != "country" {
730+ if ! strings .EqualFold (field , "country" ) {
730731 return ""
731732 }
732733
0 commit comments