From 1739ecabe207265597961053be52a54fa20677cb Mon Sep 17 00:00:00 2001 From: Sebastian Czech Date: Thu, 4 Apr 2024 10:09:50 +0200 Subject: [PATCH] Refactor Underscore function --- pkg/naming/names.go | 108 +++++++++++++++++++++------------------ pkg/naming/names_test.go | 5 ++ pkg/translate/imports.go | 1 + 3 files changed, 65 insertions(+), 49 deletions(-) diff --git a/pkg/naming/names.go b/pkg/naming/names.go index cd4f06a8..222942c6 100644 --- a/pkg/naming/names.go +++ b/pkg/naming/names.go @@ -74,88 +74,98 @@ func (o *Namer) NewSlug(name string) string { // sections within the string, preserving their original form. func CamelCase(prefix, value, suffix string, capitalizeFirstRune bool) string { var builder strings.Builder - builder.Grow(len(prefix) + len(value) + len(suffix)) - - builder.WriteString(prefix) + prepareStringBuilder(prefix, value, suffix, builder) isFirstCharacter := true hasFirstRuneBeenCapitalized := false isIgnoringTemplate := false for _, runeValue := range value { - switch runeValue { - case '{': - isIgnoringTemplate = true - isFirstCharacter = true // Reset for the content after template - continue - case '}': - isIgnoringTemplate = false + if isTemplateDelimiter(runeValue, &isIgnoringTemplate) { continue } - if isIgnoringTemplate { - continue - } - - if shouldResetFirstCharacterFlag(runeValue) { - isFirstCharacter = true - } else if isFirstCharacter { - capitalizeAndWriteRune(&builder, runeValue, hasFirstRuneBeenCapitalized || capitalizeFirstRune) - hasFirstRuneBeenCapitalized = true - isFirstCharacter = false - } else { - builder.WriteRune(runeValue) - } + writeRuneAndApplyChangesForCamelCase(runeValue, &builder, &isFirstCharacter, &hasFirstRuneBeenCapitalized, &capitalizeFirstRune) } builder.WriteString(suffix) return builder.String() } +// writeRuneAndApplyChangesForCamelCase contains logic to check all conditions for create CamelCase names and writes rune value. +func writeRuneAndApplyChangesForCamelCase(runeValue int32, builder *strings.Builder, isFirstCharacter *bool, hasFirstRuneBeenCapitalized *bool, capitalizeFirstRune *bool) { + if shouldResetFirstCharacterFlag(runeValue) { + *isFirstCharacter = true + } else if *isFirstCharacter { + capitalizeAndWriteRune(builder, runeValue, *hasFirstRuneBeenCapitalized || *capitalizeFirstRune) + *hasFirstRuneBeenCapitalized = true + *isFirstCharacter = false + } else { + builder.WriteRune(runeValue) + } +} + // Underscore converts a string to under_score format, allowing for optional prefixes/suffixes. // It also skips over templated sections within the string, preserving their original form. func Underscore(prefix, value, suffix string) string { var builder strings.Builder - builder.Grow(len(prefix) + len(value) + len(suffix)) - - builder.WriteString(prefix) + prepareStringBuilder(prefix, value, suffix, builder) isFirstCharacter := true isIgnoringTemplate := false for _, runeValue := range value { - switch runeValue { - case '{': - isIgnoringTemplate = true - isFirstCharacter = true // Reset for the content after template - continue - case '}': - isIgnoringTemplate = false - continue - } - - if isIgnoringTemplate { + if isTemplateDelimiter(runeValue, &isIgnoringTemplate) { continue } - if shouldResetFirstCharacterFlag(runeValue) { - builder.WriteRune('_') - isFirstCharacter = true - } else if isFirstCharacter { - builder.WriteRune(unicode.ToLower(runeValue)) - isFirstCharacter = false - } else if unicode.IsUpper(runeValue) { - builder.WriteRune('_') - builder.WriteRune(unicode.ToLower(runeValue)) - } else { - builder.WriteRune(unicode.ToLower(runeValue)) - } + writeRuneAndApplyChangesForUnderscore(runeValue, &builder, &isFirstCharacter) } builder.WriteString(suffix) return builder.String() } +// writeRuneAndApplyChangesForUnderscore contains logic to check all conditions for create under_score names and writes rune value. +func writeRuneAndApplyChangesForUnderscore(runeValue int32, builder *strings.Builder, isFirstCharacter *bool) { + if shouldResetFirstCharacterFlag(runeValue) { + appendUnderscore(builder) + *isFirstCharacter = true + } else if *isFirstCharacter { + capitalizeAndWriteRune(builder, runeValue, false) + *isFirstCharacter = false + } else if unicode.IsUpper(runeValue) { + appendUnderscore(builder) + capitalizeAndWriteRune(builder, runeValue, false) + } else { + capitalizeAndWriteRune(builder, runeValue, false) + } +} + +// appendUnderscore add _ to builder, from which final result is built. +func appendUnderscore(builder *strings.Builder) { + builder.WriteRune('_') +} + +// isTemplateDelimiter return true, if { or } are runeValue or isIgnoringTemplate is set to true. +func isTemplateDelimiter(runeValue int32, isIgnoringTemplate *bool) bool { + switch runeValue { + case '{': + *isIgnoringTemplate = true + return true + case '}': + *isIgnoringTemplate = false + return true // if we finish template, then we always ignore that character, even if set isIgnoringTemplate to false + } + + return *isIgnoringTemplate +} + +func prepareStringBuilder(prefix string, value string, suffix string, builder strings.Builder) { + builder.Grow(len(prefix) + len(value) + len(suffix)) + builder.WriteString(prefix) +} + // shouldResetFirstCharacterFlag checks if the given rune is a separator that should trigger // the next character to be capitalized in CamelCase conversion. func shouldResetFirstCharacterFlag(r rune) bool { diff --git a/pkg/naming/names_test.go b/pkg/naming/names_test.go index 66f51394..9e086cfe 100644 --- a/pkg/naming/names_test.go +++ b/pkg/naming/names_test.go @@ -8,6 +8,9 @@ import ( func TestCamelCase(t *testing.T) { assert.Equal(t, "CamelCase", CamelCase("", "camel_case", "", true)) assert.Equal(t, "camelCase", CamelCase("", "camel_case", "", false)) + assert.Equal(t, "camelCase", CamelCase("", "camel_case", "", false)) + assert.Equal(t, "camelCase", CamelCase("", "camel_{template_example}case", "", false)) + assert.Equal(t, "camelCase", CamelCase("", "camel_case{template_example}", "", false)) } func TestUnderscore(t *testing.T) { @@ -15,6 +18,8 @@ func TestUnderscore(t *testing.T) { assert.Equal(t, "under_score", Underscore("", "under_score", "")) assert.Equal(t, "under_score", Underscore("", "UnderScore", "")) assert.Equal(t, "under_score", Underscore("", "underScore", "")) + assert.Equal(t, "under_score", Underscore("", "underScore{template_example}", "")) + assert.Equal(t, "under_score", Underscore("", "under{template_example}Score", "")) } func TestAlphaNumeric(t *testing.T) { diff --git a/pkg/translate/imports.go b/pkg/translate/imports.go index f4d0fec9..0eb5b417 100644 --- a/pkg/translate/imports.go +++ b/pkg/translate/imports.go @@ -2,6 +2,7 @@ package translate import "github.com/paloaltonetworks/pan-os-codegen/pkg/imports" +// RenderImports render string, which contains import required in entry, location or service template. func RenderImports(templateType string) (string, error) { manager := imports.NewManager()