Skip to content

Commit 871319b

Browse files
committed
Implement PascalCase()
- PascalCase is upper camel case, ie. SomethingLikeThis - CamelCase is lower camel case, ie. somethingLikeThis
1 parent 55146e5 commit 871319b

File tree

6 files changed

+88
-44
lines changed

6 files changed

+88
-44
lines changed

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,25 @@
22

33
[![GoDoc Widget]][GoDoc]
44

5-
Golang pkg to convert any text input to ASCII CamelCase or snake_case via a fast state machine parser.
5+
Golang pkg to convert any text input to camelCase, PascalCase or snake_case via a fast state machine parser. Removes all whitespaces and special characters. Supports Unicode characters.
66

7-
## Usage:
7+
## Usage
88
```go
99
import "github.com/golang-cz/textcase"
1010
```
1111

1212
```go
13-
textcase.CamelCase("Hello World!!")
13+
textcase.CamelCase("Hello World!")
14+
// helloWorld
15+
```
16+
17+
```go
18+
textcase.CamelCase("Hello World!")
1419
// HelloWorld
1520
```
1621

1722
```go
18-
textcase.SnakeCase("Hello World!!")
23+
textcase.SnakeCase("Hello World!")
1924
// hello_world
2025
```
2126

camel.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,23 @@ import (
66
"unicode/utf8"
77
)
88

9-
func CamelCase(str string) string {
9+
// Converts input string to "camelCase" (lower camel case) naming convention.
10+
// Removes all whitespace and special characters. Supports Unicode characters.
11+
func CamelCase(input string) string {
1012
var b strings.Builder
1113

1214
stateMachine := idle
13-
for i := 0; i < len(str); {
14-
r, size := utf8.DecodeRuneInString(str[i:])
15+
for i := 0; i < len(input); {
16+
r, size := utf8.DecodeRuneInString(input[i:])
1517
i += size
1618
stateMachine = stateMachine.next(r)
1719
switch stateMachine {
1820
case firstAlphaNum:
19-
b.WriteRune(unicode.ToUpper(r))
21+
if b.Len() > 0 {
22+
b.WriteRune(unicode.ToUpper(r))
23+
} else {
24+
b.WriteRune(unicode.ToLower(r))
25+
}
2026
case alphaNum:
2127
b.WriteRune(unicode.ToLower(r))
2228
}

camelsnake_test.go

Lines changed: 0 additions & 36 deletions
This file was deleted.

pascal.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package textcase
2+
3+
import (
4+
"strings"
5+
"unicode"
6+
"unicode/utf8"
7+
)
8+
9+
// Converts input string to "PascalCase" (upper camel case) naming convention.
10+
// Removes all whitespace and special characters. Supports Unicode characters.
11+
func PascalCase(input string) string {
12+
var b strings.Builder
13+
14+
stateMachine := idle
15+
for i := 0; i < len(input); {
16+
r, size := utf8.DecodeRuneInString(input[i:])
17+
i += size
18+
stateMachine = stateMachine.next(r)
19+
switch stateMachine {
20+
case firstAlphaNum:
21+
b.WriteRune(unicode.ToUpper(r))
22+
case alphaNum:
23+
b.WriteRune(unicode.ToLower(r))
24+
}
25+
}
26+
return b.String()
27+
}

snake.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"unicode/utf8"
77
)
88

9+
// Converts input string to "snake_case" naming convention.
10+
// Removes all whitespace and special characters. Supports Unicode characters.
911
func SnakeCase(str string) string {
1012
var b bytes.Buffer
1113

textcase_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package textcase
2+
3+
import (
4+
"strings"
5+
"testing"
6+
)
7+
8+
func TestTextCases(t *testing.T) {
9+
t.Parallel()
10+
11+
tt := []struct {
12+
in string
13+
camel string
14+
snake string
15+
}{
16+
{in: "Add updated_at to users table", camel: "addUpdatedAtToUsersTable", snake: "add_updated_at_to_users_table"},
17+
{in: "$()&^%(_--crazy__--input$)", camel: "crazyInput", snake: "crazy_input"},
18+
{in: "Hey, this TEXT will have to obey some rules!!", camel: "heyThisTextWillHaveToObeySomeRules", snake: "hey_this_text_will_have_to_obey_some_rules"},
19+
{in: "_$$_This is some text, OK?!", camel: "thisIsSomeTextOk", snake: "this_is_some_text_ok"},
20+
{in: "_", camel: "", snake: ""},
21+
{in: "$(((*&^%$#@!)))#$%^&*", camel: "", snake: ""},
22+
{in: "", camel: "", snake: ""},
23+
{in: "a", camel: "a", snake: "a"},
24+
{in: "a___", camel: "a", snake: "a"},
25+
{in: "a___b", camel: "aB", snake: "a_b"},
26+
{in: "ax___by", camel: "axBy", snake: "ax_by"},
27+
}
28+
29+
for _, test := range tt {
30+
if got := CamelCase(test.in); got != test.camel {
31+
t.Errorf("unexpected camelCase for input(%q), got %q, want %q", test.in, got, test.camel)
32+
}
33+
if got := PascalCase(test.in); got != strings.Title(test.camel) {
34+
t.Errorf("unexpected PascalCase for input(%q), got %q, want %q", test.in, got, strings.Title(test.camel))
35+
}
36+
if got := SnakeCase(test.in); got != test.snake {
37+
t.Errorf("unexpected snake_case for input(%q), got %q, want %q", test.in, got, test.snake)
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)