ut/utini/names.go

87 lines
1.8 KiB
Go

package utini
import (
"strings"
"unicode"
)
type characterCasing int
const (
undefinedCase characterCasing = iota
lowerCase
upperCase
)
func camelCaseToSnakeCase(name string) string {
segments := strings.Split(name, ".")
if len(segments) > 1 {
for i, segment := range segments {
segments[i] = camelCaseToSnakeCase(segment)
}
return strings.Join(segments, ".")
}
var words []string
runes := []rune(name)
if len(runes) == 0 {
return ""
}
n := len(runes)
end := n
casing := undefinedCase
for i := range runes {
j := n - i - 1
r := runes[j]
if unicode.IsLower(r) {
if casing == upperCase {
words = append(words, strings.ToLower(string(runes[j+1:end])))
end = j + 1
casing = undefinedCase
} else {
casing = lowerCase
}
} else if r == '_' {
if end-j > 1 {
words = append(words, strings.ToLower(string(runes[j+1:end])))
end = j
}
casing = undefinedCase
} else if unicode.IsDigit(r) { // acts like either upper or lowercase depending on which character was following.
} else {
if casing == lowerCase {
words = append(words, strings.ToLower(string(runes[j:end])))
end = j
casing = undefinedCase
} else {
casing = upperCase
}
}
}
if end > 0 {
words = append(words, strings.ToLower(string(runes[:end])))
}
// reverse order of words
last := len(words) - 1
for i := 0; i < len(words)/2; i++ {
words[i], words[last-i] = words[last-i], words[i]
}
return strings.Join(words, "_")
}
func snakeCaseToCamelCase(name string) string {
words := strings.Split(name, `_`)
for i, word := range words {
runes := []rune(word)
first := strings.IndexFunc(word, unicode.IsLetter)
if first > -1 {
runes[first] = unicode.ToUpper(runes[first])
}
words[i] = string(runes)
}
return strings.Join(words, ``)
}