From 2b0d1ac3872658fa14c4a6922c0114508cd399c6 Mon Sep 17 00:00:00 2001 From: Ivan Matmati Date: Wed, 4 Dec 2024 10:42:45 +0100 Subject: [PATCH] MINOR: dashcase rewrite for performance --- misc/stringutil.go | 52 ++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/misc/stringutil.go b/misc/stringutil.go index b9418ac0..342bdd5a 100644 --- a/misc/stringutil.go +++ b/misc/stringutil.go @@ -109,38 +109,32 @@ func SnakeCase(fieldName string) string { } // DashCase turns camel case to snake case string -func DashCase(fieldName string) string { - fieldName = strings.Trim(fieldName, " ") - n := "" - for i, v := range fieldName { - // treat acronyms as words, eg for JSONData -> JSON is a whole word - nextCaseIsChanged := false - if i+1 < len(fieldName) { - next := fieldName[i+1] - if (v >= 'A' && v <= 'Z' && next >= 'a' && next <= 'z') || (v >= 'a' && v <= 'z' && next >= 'A' && next <= 'Z') { - nextCaseIsChanged = true +func DashCase(input string) string { + var result strings.Builder + n := len(input) + // Grow to worst case where a dash is inserted every character. + result.Grow(n * 2) + + for i, r := range input { + // if r is capital .. + if r >= 'A' && r <= 'Z' { + // add a dash before if : + // 1. we're not on the first or last character. + // 2. the previous character is not capital. + // 3. the next character is not capital. + // To understand the rules take "JSONData" -> "json-data" as an example + if i > 0 && !(input[i-1] >= 'A' && input[i-1] <= 'Z' && (i+1 == n || i+1 < n && input[i+1] >= 'A' && input[i+1] <= 'Z')) { + result.WriteByte('-') } - } - - switch { - case i > 0 && n[len(n)-1] != '-' && nextCaseIsChanged: - // add underscore if next letter case type is changed - if v >= 'A' && v <= 'Z' { - n += "-" + string(v) - } else if v >= 'a' && v <= 'z' { - n += string(v) + "-" - } - case v == ' ': - // replace spaces with underscores - n += "-" - default: - n += string(v) + // Lower the case of the character + result.WriteByte(byte(r + ('a' - 'A'))) + } else { + // If lowercase just write it + result.WriteRune(r) } } - n = strings.ToLower(n) - // special case - n = strings.ReplaceAll(n, "httpuri", "http-uri") - return n + + return strings.ReplaceAll(result.String(), "httpuri", "http-uri") } func ParseSize(size string) *int64 {