Skip to content
This repository was archived by the owner on Jun 12, 2024. It is now read-only.

Commit 8dccb68

Browse files
authored
Support more cases for underscore casing conversion (#52)
* `created_at DESC` -> `created_at_desc` * de-duplication of underscore characters.
1 parent 108571f commit 8dccb68

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

pkg/strings/casing.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,33 @@ func ToPascalCase(value string) string {
3737
func ToUnderscoreCase(value string) string {
3838
b := strings.Builder{}
3939

40+
var previousUnderscore, previousUppercase bool
41+
4042
for _, rune := range value {
41-
// Always upper the character after non-letter/non-digit skipping the character
43+
44+
// if it's not allowed character we replace it with underscore without
45+
// duplication of underscores
4246
if !unicode.IsLetter(rune) && !unicode.IsDigit(rune) {
43-
b.WriteByte('_')
47+
if !previousUnderscore {
48+
b.WriteByte('_')
49+
previousUnderscore = true
50+
}
51+
previousUppercase = false
4452
continue
4553
}
4654

47-
// convert pascal or camel case into underscore case
4855
if unicode.IsUpper(rune) {
49-
b.WriteByte('_')
56+
if !previousUnderscore && !previousUppercase {
57+
b.WriteByte('_')
58+
}
59+
b.WriteRune(unicode.ToLower(rune))
60+
previousUppercase = true
61+
} else {
62+
b.WriteRune(rune)
63+
previousUppercase = false
5064
}
5165

52-
b.WriteRune(unicode.ToLower(rune))
66+
previousUnderscore = false
5367
}
5468

5569
return strings.Trim(b.String(), "_")

pkg/strings/casing_test.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ func TestToUnderscoreCase(t *testing.T) {
6767
input: "some_table_nameSomeName",
6868
output: "some_table_name_some_name",
6969
},
70+
{
71+
name: "Does not double underscores",
72+
input: "some Table Name",
73+
output: "some_table_name",
74+
},
75+
{
76+
name: "Respects several capital letters in a row",
77+
input: "some TABLE NAME",
78+
output: "some_table_name",
79+
},
7080
{
7181
name: "Does not change the value if it's underscore casing",
7282
input: "some_name",
@@ -82,7 +92,16 @@ func TestToUnderscoreCase(t *testing.T) {
8292
input: "Some{{{",
8393
output: "some",
8494
},
85-
95+
{
96+
name: "Makes a separate upper case word a part of underscored identifier",
97+
input: "created_at DESC",
98+
output: "created_at_desc",
99+
},
100+
{
101+
name: "Makes a separate upper case word a part of underscored identifier",
102+
input: "word$^%^%another _some *&^%$A%$#%WORD",
103+
output: "word_another_some_a_word",
104+
},
86105
{
87106
name: "Handles empty string",
88107
},

0 commit comments

Comments
 (0)