94 lines
1.7 KiB
Go
94 lines
1.7 KiB
Go
package strcase
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
splitRE = regexp.MustCompile(`_+|-+|\s+`)
|
|
allCapsRE = regexp.MustCompile(`^[A-Z]{2,}\d*$`)
|
|
capitalizedRE = regexp.MustCompile(`[A-Z][a-z]+\d*`)
|
|
)
|
|
|
|
type CamelContext interface {
|
|
UseCaps(a []string) CamelContext
|
|
HasCaps(w string) bool
|
|
Find(s string) (string, bool)
|
|
Save(s, r string)
|
|
}
|
|
|
|
type camelContext struct {
|
|
allCaps map[string]bool
|
|
cache map[string]string
|
|
}
|
|
|
|
func (c *camelContext) UseCaps(a []string) CamelContext {
|
|
if c.allCaps == nil {
|
|
c.allCaps = make(map[string]bool, len(a))
|
|
}
|
|
for _, s := range a {
|
|
c.allCaps[s] = true
|
|
}
|
|
return c
|
|
}
|
|
|
|
func (c *camelContext) HasCaps(w string) (ok bool) {
|
|
if c.allCaps != nil {
|
|
_, ok = c.allCaps[w]
|
|
}
|
|
return
|
|
}
|
|
func (c *camelContext) Find(s string) (r string, ok bool) {
|
|
if c.cache != nil {
|
|
r, ok = c.cache[s]
|
|
}
|
|
return
|
|
}
|
|
|
|
func (c *camelContext) Save(s, r string) {
|
|
if c.cache == nil {
|
|
c.cache = make(map[string]string)
|
|
}
|
|
c.cache[s] = r
|
|
}
|
|
|
|
func NewCamelContext(caps []string) CamelContext {
|
|
return new(camelContext).UseCaps(caps)
|
|
}
|
|
|
|
func ToCamel(s string, c ...CamelContext) (r string) {
|
|
var ctx CamelContext
|
|
if len(c) > 0 {
|
|
ctx = c[0]
|
|
}
|
|
if ctx != nil {
|
|
var ok bool
|
|
if r, ok = ctx.Find(s); ok {
|
|
return
|
|
}
|
|
}
|
|
words := splitRE.Split(s, -1)
|
|
for i, word := range words {
|
|
if len(word) != 0 {
|
|
if allCapsRE.MatchString(word) {
|
|
words[i] = word[:1] + strings.ToLower(word[1:])
|
|
} else {
|
|
words[i] = strings.ToUpper(word[:1]) + word[1:]
|
|
}
|
|
}
|
|
}
|
|
if ctx != nil {
|
|
r = capitalizedRE.ReplaceAllStringFunc(strings.Join(words, ""), func(s string) string {
|
|
if w := strings.ToUpper(s); ctx.HasCaps(w) {
|
|
return w
|
|
}
|
|
return s
|
|
})
|
|
ctx.Save(s, r)
|
|
} else {
|
|
r = strings.Join(words, "")
|
|
}
|
|
return
|
|
}
|