Skip to content

Commit

Permalink
Merge pull request #76 from gofiber/feat-if-to-lower
Browse files Browse the repository at this point in the history
feat: Add IfToLower and IfToUpper functions for converting ASCII strings to lowercase and uppercase respectively
  • Loading branch information
ReneWerner87 authored Mar 25, 2024
2 parents b1e3dbb + edefd68 commit 0a843fb
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
46 changes: 46 additions & 0 deletions strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,49 @@ func ToUpper(b string) string {

return UnsafeString(res)
}

// IfToUpper returns an lowercase version of the input ASCII string.
//
// It first checks if the string contains any uppercase characters before converting it.
//
// For strings that are already lowercase,this function will be faster than `ToLower`.
//
// In the case of mixed-case or uppercase strings, this function will be slightly slower than `ToLower`.
func IfToLower(s string) string {
hasUpper := false
for i := 0; i < len(s); i++ {
c := s[i]
if toLowerTable[c] != c {
hasUpper = true
break
}
}

if !hasUpper {
return s
}
return ToLower(s)
}

// IfToUpper returns an uppercase version of the input ASCII string.
//
// It first checks if the string contains any lowercase characters before converting it.
//
// For strings that are already uppercase,this function will be faster than `ToUpper`.
//
// In the case of mixed-case or lowercase strings, this function will be slightly slower than `ToUpper`.
func IfToUpper(s string) string {
hasLower := false
for i := 0; i < len(s); i++ {
c := s[i]
if toUpperTable[c] != c {
hasLower = true
break
}
}

if !hasLower {
return s
}
return ToUpper(s)
}
63 changes: 63 additions & 0 deletions strings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ func Benchmark_ToUpper(b *testing.B) {
}
require.Equal(b, upperStr, res)
})
b.Run("IfToUpper-Upper", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = IfToUpper(upperStr)
}
require.Equal(b, upperStr, res)
})
b.Run("IfToUpper-Mixed", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = IfToUpper(largeStr)
}
require.Equal(b, upperStr, res)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = strings.ToUpper(largeStr)
Expand All @@ -55,10 +67,61 @@ func Benchmark_ToLower(b *testing.B) {
}
require.Equal(b, lowerStr, res)
})
b.Run("IfToLower-Lower", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = IfToLower(lowerStr)
}
require.Equal(b, lowerStr, res)
})
b.Run("IfToLower-Mixed", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = IfToLower(largeStr)
}
require.Equal(b, lowerStr, res)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = strings.ToLower(largeStr)
}
require.Equal(b, lowerStr, res)
})
}

func Test_IfToUpper(t *testing.T) {
t.Parallel()
require.Equal(t, "MYNAMEISPARAM", IfToUpper("MYNAMEISPARAM")) // already uppercase
require.Equal(t, "MYNAMEISPARAM", IfToUpper("mynameisparam")) // lowercase to uppercase
require.Equal(t, "MYNAMEISPARAM", IfToUpper("MyNameIsParam")) // mixed case
}

func Test_IfToLower(t *testing.T) {
t.Parallel()
require.Equal(t, "mynameisparam", IfToLower("mynameisparam")) // already lowercase
require.Equal(t, "mynameisparam", IfToLower("myNameIsParam")) // mixed case
require.Equal(t, "https://gofiber.io", IfToLower("https://gofiber.io")) // Origin Header Type URL
require.Equal(t, "mynameisparam", IfToLower("MYNAMEISPARAM")) // uppercase to lowercase
}

// Benchmark_IfToLower_HeadersOrigin benchmarks the IfToLower function with an origin header type URL.
// These headers are typically lowercase, so the function should return the input string without modification.
func Benchmark_IfToToLower_HeadersOrigin(b *testing.B) {
var res string
b.Run("fiber", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = ToLower("https://gofiber.io")
}
require.Equal(b, "https://gofiber.io", res)
})
b.Run("IfToLower-Lower", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = IfToLower("https://gofiber.io")
}
require.Equal(b, "https://gofiber.io", res)
})
b.Run("default", func(b *testing.B) {
for n := 0; n < b.N; n++ {
res = strings.ToLower("https://gofiber.io")
}
require.Equal(b, "https://gofiber.io", res)
})
}

0 comments on commit 0a843fb

Please sign in to comment.