Skip to content

Commit d6add30

Browse files
1 parent 9eba861 commit d6add30

File tree

2 files changed

+63
-64
lines changed

2 files changed

+63
-64
lines changed

client_initialize_response.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,9 @@ func getClientInitializeResponse(
116116
baseSpecInitializeResponse: base,
117117
Value: evalRes.JsonValue,
118118
Group: evalRes.RuleID,
119-
IsDeviceBased: strings.ToLower(spec.IDType) == "stableid",
119+
IsDeviceBased: strings.EqualFold(spec.IDType, "stableid"),
120120
}
121-
entityType := strings.ToLower(spec.Entity)
122-
if entityType == "experiment" {
121+
if strings.EqualFold(spec.Entity, "experiment") {
123122
result.IsUserInExperiment = new(bool)
124123
*result.IsUserInExperiment = evalRes.IsExperimentGroup != nil && *evalRes.IsExperimentGroup
125124
result.IsExperimentActive = new(bool)
@@ -148,7 +147,7 @@ func getClientInitializeResponse(
148147
baseSpecInitializeResponse: base,
149148
Value: evalResult.JsonValue,
150149
Group: evalResult.RuleID,
151-
IsDeviceBased: strings.ToLower(spec.IDType) == "stableid",
150+
IsDeviceBased: strings.EqualFold(spec.IDType, "stableid"),
152151
UndelegatedSecondaryExposures: evalResult.UndelegatedSecondaryExposures,
153152
}
154153
delegate := evalResult.ConfigDelegate
@@ -190,8 +189,7 @@ func getClientInitializeResponse(
190189
if !spec.hasTargetAppID(appId) {
191190
continue
192191
}
193-
entityType := strings.ToLower(spec.Entity)
194-
if entityType != "segment" && entityType != "holdout" {
192+
if !strings.EqualFold(spec.Entity, "segment") && !strings.EqualFold(spec.Entity, "holdout") {
195193
hashedName, res := gateToResponse(name, spec)
196194
featureGates[hashedName] = res
197195
}

evaluator.go

Lines changed: 59 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -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

449449
func 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

479479
func (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
656657
func 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

728729
func 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

Comments
 (0)