1
0
mirror of https://github.com/ManyakRus/crud_generator.git synced 2024-12-22 00:36:41 +02:00
crud_generator/vendor/github.com/serenize/snaker/snaker.go

151 lines
3.0 KiB
Go
Raw Normal View History

2023-10-24 17:03:04 +02:00
// Package snaker provides methods to convert CamelCase names to snake_case and back.
// It considers the list of allowed initialsms used by github.com/golang/lint/golint (e.g. ID or HTTP)
package snaker
import (
"strings"
"unicode"
)
// CamelToSnake converts a given string to snake case
func CamelToSnake(s string) string {
var result string
var words []string
var lastPos int
rs := []rune(s)
for i := 0; i < len(rs); i++ {
if i > 0 && unicode.IsUpper(rs[i]) {
if initialism := startsWithInitialism(s[lastPos:]); initialism != "" {
words = append(words, initialism)
i += len(initialism) - 1
lastPos = i
continue
}
words = append(words, s[lastPos:i])
lastPos = i
}
}
// append the last word
if s[lastPos:] != "" {
words = append(words, s[lastPos:])
}
for k, word := range words {
if k > 0 {
result += "_"
}
result += strings.ToLower(word)
}
return result
}
func snakeToCamel(s string, upperCase bool) string {
var result string
words := strings.Split(s, "_")
for i, word := range words {
if exception := snakeToCamelExceptions[word]; len(exception) > 0 {
result += exception
continue
}
if upperCase || i > 0 {
if upper := strings.ToUpper(word); commonInitialisms[upper] {
result += upper
continue
}
}
if (upperCase || i > 0) && len(word) > 0 {
w := []rune(word)
w[0] = unicode.ToUpper(w[0])
result += string(w)
} else {
result += word
}
}
return result
}
// SnakeToCamel returns a string converted from snake case to uppercase
func SnakeToCamel(s string) string {
return snakeToCamel(s, true)
}
// SnakeToCamelLower returns a string converted from snake case to lowercase
func SnakeToCamelLower(s string) string {
return snakeToCamel(s, false)
}
// startsWithInitialism returns the initialism if the given string begins with it
func startsWithInitialism(s string) string {
var initialism string
// the longest initialism is 5 char, the shortest 2
for i := 1; i <= 5; i++ {
if len(s) > i-1 && commonInitialisms[s[:i]] {
initialism = s[:i]
}
}
return initialism
}
// commonInitialisms, taken from
// https://github.com/golang/lint/blob/206c0f020eba0f7fbcfbc467a5eb808037df2ed6/lint.go#L731
var commonInitialisms = map[string]bool{
"ACL": true,
"API": true,
"ASCII": true,
"CPU": true,
"CSS": true,
"DNS": true,
"EOF": true,
"ETA": true,
"GPU": true,
"GUID": true,
"HTML": true,
"HTTP": true,
"HTTPS": true,
"ID": true,
"IP": true,
"JSON": true,
"LHS": true,
"OS": true,
"QPS": true,
"RAM": true,
"RHS": true,
"RPC": true,
"SLA": true,
"SMTP": true,
"SQL": true,
"SSH": true,
"TCP": true,
"TLS": true,
"TTL": true,
"UDP": true,
"UI": true,
"UID": true,
"UUID": true,
"URI": true,
"URL": true,
"UTF8": true,
"VM": true,
"XML": true,
"XMPP": true,
"XSRF": true,
"XSS": true,
"OAuth": true,
}
// add exceptions here for things that are not automatically convertable
var snakeToCamelExceptions = map[string]string{
"oauth": "OAuth",
}