Skip to content

Commit 999a088

Browse files
authored
Merge pull request #77 from gofiber/backport-if-to-lower
feat: backport IfToLower and IfToUpper functions from v2
2 parents 6cd3dea + f0cce84 commit 999a088

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

strings.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,49 @@ func DefaultString(value string, defaultValue string) string {
6868
}
6969
return value
7070
}
71+
72+
// IfToUpper returns an lowercase version of the input ASCII string.
73+
//
74+
// It first checks if the string contains any uppercase characters before converting it.
75+
//
76+
// For strings that are already lowercase,this function will be faster than `ToLower`.
77+
//
78+
// In the case of mixed-case or uppercase strings, this function will be slightly slower than `ToLower`.
79+
func IfToLower(s string) string {
80+
hasUpper := false
81+
for i := 0; i < len(s); i++ {
82+
c := s[i]
83+
if toLowerTable[c] != c {
84+
hasUpper = true
85+
break
86+
}
87+
}
88+
89+
if !hasUpper {
90+
return s
91+
}
92+
return ToLower(s)
93+
}
94+
95+
// IfToUpper returns an uppercase version of the input ASCII string.
96+
//
97+
// It first checks if the string contains any lowercase characters before converting it.
98+
//
99+
// For strings that are already uppercase,this function will be faster than `ToUpper`.
100+
//
101+
// In the case of mixed-case or lowercase strings, this function will be slightly slower than `ToUpper`.
102+
func IfToUpper(s string) string {
103+
hasLower := false
104+
for i := 0; i < len(s); i++ {
105+
c := s[i]
106+
if toUpperTable[c] != c {
107+
hasLower = true
108+
break
109+
}
110+
}
111+
112+
if !hasLower {
113+
return s
114+
}
115+
return ToUpper(s)
116+
}

strings_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ func Benchmark_ToUpper(b *testing.B) {
2525
}
2626
AssertEqual(b, "/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS", res)
2727
})
28+
b.Run("IfToUpper-Upper", func(b *testing.B) {
29+
for n := 0; n < b.N; n++ {
30+
res = IfToUpper("/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS")
31+
}
32+
AssertEqual(b, "/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS", res)
33+
})
34+
b.Run("IfToUpper-Mixed", func(b *testing.B) {
35+
for n := 0; n < b.N; n++ {
36+
res = IfToUpper(path)
37+
}
38+
AssertEqual(b, "/REPOS/GOFIBER/FIBER/ISSUES/187643/COMMENTS", res)
39+
})
2840
b.Run("default", func(b *testing.B) {
2941
for n := 0; n < b.N; n++ {
3042
res = strings.ToUpper(path)
@@ -56,6 +68,18 @@ func Benchmark_ToLower(b *testing.B) {
5668
}
5769
AssertEqual(b, "/repos/gofiber/fiber/issues/187643/comments", res)
5870
})
71+
b.Run("IfToLower-Lower", func(b *testing.B) {
72+
for n := 0; n < b.N; n++ {
73+
res = IfToLower("/repos/gofiber/fiber/issues/187643/comments")
74+
}
75+
AssertEqual(b, "/repos/gofiber/fiber/issues/187643/comments", res)
76+
})
77+
b.Run("IfToLower-Mixed", func(b *testing.B) {
78+
for n := 0; n < b.N; n++ {
79+
res = IfToLower(path)
80+
}
81+
AssertEqual(b, "/repos/gofiber/fiber/issues/187643/comments", res)
82+
})
5983
b.Run("default", func(b *testing.B) {
6084
for n := 0; n < b.N; n++ {
6185
res = strings.ToLower(path)
@@ -147,3 +171,42 @@ func Benchmark_Trim(b *testing.B) {
147171
AssertEqual(b, "foobar", res)
148172
})
149173
}
174+
175+
func Test_IfToUpper(t *testing.T) {
176+
t.Parallel()
177+
AssertEqual(t, "MYNAMEISPARAM", IfToUpper("MYNAMEISPARAM")) // already uppercase
178+
AssertEqual(t, "MYNAMEISPARAM", IfToUpper("mynameisparam")) // lowercase to uppercase
179+
AssertEqual(t, "MYNAMEISPARAM", IfToUpper("MyNameIsParam")) // mixed case
180+
}
181+
182+
func Test_IfToLower(t *testing.T) {
183+
t.Parallel()
184+
AssertEqual(t, "mynameisparam", IfToLower("mynameisparam")) // already lowercase
185+
AssertEqual(t, "mynameisparam", IfToLower("myNameIsParam")) // mixed case
186+
AssertEqual(t, "https://gofiber.io", IfToLower("https://gofiber.io")) // Origin Header Type URL
187+
AssertEqual(t, "mynameisparam", IfToLower("MYNAMEISPARAM")) // uppercase to lowercase
188+
}
189+
190+
// Benchmark_IfToLower_HeadersOrigin benchmarks the IfToLower function with an origin header type URL.
191+
// These headers are typically lowercase, so the function should return the input string without modification.
192+
func Benchmark_IfToToLower_HeadersOrigin(b *testing.B) {
193+
var res string
194+
b.Run("fiber", func(b *testing.B) {
195+
for n := 0; n < b.N; n++ {
196+
res = ToLower("https://gofiber.io")
197+
}
198+
AssertEqual(b, "https://gofiber.io", res)
199+
})
200+
b.Run("IfToLower-Lower", func(b *testing.B) {
201+
for n := 0; n < b.N; n++ {
202+
res = IfToLower("https://gofiber.io")
203+
}
204+
AssertEqual(b, "https://gofiber.io", res)
205+
})
206+
b.Run("default", func(b *testing.B) {
207+
for n := 0; n < b.N; n++ {
208+
res = strings.ToLower("https://gofiber.io")
209+
}
210+
AssertEqual(b, "https://gofiber.io", res)
211+
})
212+
}

0 commit comments

Comments
 (0)