From 15ea874a75c253aa979d2cb8423fbe05e41a2158 Mon Sep 17 00:00:00 2001 From: Patrick O'brien Date: Mon, 8 Aug 2016 09:34:11 +1000 Subject: [PATCH] Add SnakeCase --- strmangle/strmangle.go | 17 +++++++++++++++++ strmangle/strmangle_test.go | 29 +++++++++++++++++++++++++++++ templates.go | 3 ++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/strmangle/strmangle.go b/strmangle/strmangle.go index 3fdde19..7890d9e 100644 --- a/strmangle/strmangle.go +++ b/strmangle/strmangle.go @@ -9,6 +9,7 @@ import ( "math" "regexp" "strings" + "unicode" "github.com/jinzhu/inflection" ) @@ -138,6 +139,22 @@ func CamelCase(name string) string { return strings.Join(splits, "") } +// SnakeCase converts TitleCase variable names to snake_case format. +func SnakeCase(name string) string { + runes := []rune(name) + length := len(runes) + + var out []rune + for i := 0; i < length; i++ { + if i > 0 && unicode.IsUpper(runes[i]) && ((i+1 < length && unicode.IsLower(runes[i+1])) || unicode.IsLower(runes[i-1]) || unicode.IsDigit(runes[i-1])) { + out = append(out, '_') + } + out = append(out, unicode.ToLower(runes[i])) + } + + return string(out) +} + // MakeStringMap converts a map[string]string into the format: // "key": "value", "key": "value" func MakeStringMap(types map[string]string) string { diff --git a/strmangle/strmangle_test.go b/strmangle/strmangle_test.go index 5efa6ae..1f7c231 100644 --- a/strmangle/strmangle_test.go +++ b/strmangle/strmangle_test.go @@ -185,6 +185,35 @@ func TestCamelCase(t *testing.T) { } } +func TestSnakeCase(t *testing.T) { + t.Parallel() + + tests := []struct { + In string + Out string + }{ + {"ID", "id"}, + {"ID9", "id9"}, + {"Thing", "thing"}, + {"Thing92", "thing92"}, + {"ThingGUID", "thing_guid"}, + {"ThingGUIDTwo", "thing_guid_two"}, + {"ThingStuff", "thing_stuff"}, + {"ThingStuff1GUID", "thing_stuff1_guid"}, + {"ThingStuff12GUID", "thing_stuff12_guid"}, + {"ThingStuff123GUID", "thing_stuff123_guid"}, + {"GUIDThingStuffID123", "guid_thing_stuff_id123"}, + {"GUIDThingStuffID12", "guid_thing_stuff_id12"}, + {"GUIDThingStuffID1", "guid_thing_stuff_id1"}, + } + + for i, test := range tests { + if out := SnakeCase(test.In); out != test.Out { + t.Errorf("%d) Want: %q, got %q", i, test.Out, out) + } + } +} + func TestMakeStringMap(t *testing.T) { t.Parallel() diff --git a/templates.go b/templates.go index f266236..6aa74d5 100644 --- a/templates.go +++ b/templates.go @@ -119,6 +119,7 @@ var templateStringMappers = map[string]func(string) string{ "toUpper": strings.ToUpper, "titleCase": strmangle.TitleCase, "camelCase": strmangle.CamelCase, + "snakeCase": strmangle.SnakeCase, } // templateFunctions is a map of all the functions that get passed into the @@ -168,7 +169,7 @@ var templateFunctions = template.FuncMap{ "filterColumnsByDefault": bdb.FilterColumnsByDefault, "filterColumnsBySimpleDefault": bdb.FilterColumnsBySimpleDefault, "filterColumnsByAutoIncrement": bdb.FilterColumnsByAutoIncrement, - "filterColumnsByValidated": bdb.FilterColumnsByValidated, + "filterColumnsByValidated": bdb.FilterColumnsByValidated, "autoIncPrimaryKey": bdb.AutoIncPrimaryKey, "sqlColDefinitions": bdb.SQLColDefinitions, "sqlColDefStrings": bdb.SQLColDefStrings,