Implement CamelCase via new state machine

pull/154/head
Vojtech Vitek 2019-03-05 18:59:47 -05:00
parent ed924a5874
commit f35f8da02f
2 changed files with 89 additions and 0 deletions

64
helpers.go Normal file
View File

@ -0,0 +1,64 @@
package goose
import (
"strings"
"unicode"
"unicode/utf8"
)
type camelSnakeStateMachine int
const (
begin camelSnakeStateMachine = iota // 0
firstAlphaNum // 1
alphaNum // 2
delimiter // 3
)
func (s camelSnakeStateMachine) next(r rune) camelSnakeStateMachine {
switch s {
case begin:
if isAlphaNum(r) {
return firstAlphaNum
}
case firstAlphaNum:
if isAlphaNum(r) {
return alphaNum
} else {
return delimiter
}
case alphaNum:
if !isAlphaNum(r) {
return delimiter
}
case delimiter:
if isAlphaNum(r) {
return firstAlphaNum
} else {
return begin
}
}
return s
}
func lowerCamelCase(str string) string {
var b strings.Builder
stateMachine := begin
for i := 0; i < len(str); {
r, size := utf8.DecodeRuneInString(str[i:])
i += size
stateMachine = stateMachine.next(r)
switch stateMachine {
case firstAlphaNum:
b.WriteRune(unicode.ToUpper(r))
case alphaNum:
b.WriteRune(unicode.ToLower(r))
}
}
return b.String()
}
func isAlphaNum(r rune) bool {
return unicode.IsLetter(r) || unicode.IsNumber(r)
}

25
helpers_test.go Normal file
View File

@ -0,0 +1,25 @@
package goose
import (
"testing"
)
func TestCamelSnake(t *testing.T) {
tt := []struct {
in string
camel string
snake string
}{
{in: "Add updated_at to users table", camel: "addUpdatedAtToUsersTable", snake: "add_updated_at_to_users_table"},
{in: "$()&^%(_--crazy__--input$)", camel: "crazyInput", snake: "crazy_input"},
}
for _, test := range tt {
if got := lowerCamelCase(test.in); got != test.camel {
t.Errorf("unexpected lower camel for input(%q), got %q, want %q", test.in, got, test.camel)
}
// if got := snake(test.in); got != test.snake {
// t.Error("unexpected snake for input(%q), got %q, want %q", test.in, got, test.snake)
// }
}
}