mirror of https://github.com/pressly/goose.git
85 lines
1.8 KiB
Go
85 lines
1.8 KiB
Go
package goose
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
"unicode"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
type camelSnakeStateMachine int
|
|
|
|
const ( // _$$_This is some text, OK?!
|
|
idle camelSnakeStateMachine = iota // 0 ↑ ↑ ↑
|
|
firstAlphaNum // 1 ↑ ↑ ↑ ↑ ↑
|
|
alphaNum // 2 ↑↑↑ ↑ ↑↑↑ ↑↑↑ ↑
|
|
delimiter // 3 ↑ ↑ ↑ ↑ ↑
|
|
)
|
|
|
|
func (s camelSnakeStateMachine) next(r rune) camelSnakeStateMachine {
|
|
switch s {
|
|
case idle:
|
|
if isAlphaNum(r) {
|
|
return firstAlphaNum
|
|
}
|
|
case firstAlphaNum:
|
|
if isAlphaNum(r) {
|
|
return alphaNum
|
|
}
|
|
return delimiter
|
|
case alphaNum:
|
|
if !isAlphaNum(r) {
|
|
return delimiter
|
|
}
|
|
case delimiter:
|
|
if isAlphaNum(r) {
|
|
return firstAlphaNum
|
|
}
|
|
return idle
|
|
}
|
|
return s
|
|
}
|
|
|
|
func camelCase(str string) string {
|
|
var b strings.Builder
|
|
|
|
stateMachine := idle
|
|
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 snakeCase(str string) string {
|
|
var b bytes.Buffer
|
|
|
|
stateMachine := idle
|
|
for i := 0; i < len(str); {
|
|
r, size := utf8.DecodeRuneInString(str[i:])
|
|
i += size
|
|
stateMachine = stateMachine.next(r)
|
|
switch stateMachine {
|
|
case firstAlphaNum, alphaNum:
|
|
b.WriteRune(unicode.ToLower(r))
|
|
case delimiter:
|
|
b.WriteByte('_')
|
|
}
|
|
}
|
|
if stateMachine == idle {
|
|
return string(bytes.TrimSuffix(b.Bytes(), []byte{'_'}))
|
|
}
|
|
return b.String()
|
|
}
|
|
|
|
func isAlphaNum(r rune) bool {
|
|
return unicode.IsLetter(r) || unicode.IsNumber(r)
|
|
}
|