mirror of https://github.com/rocboss/paopao-ce
parent
dd22212320
commit
7ba6dc124a
@ -0,0 +1,10 @@
|
||||
// Copyright 2020 Michael Li <alimy@gility.net>. All rights reserved.
|
||||
// Use of this source code is governed by Apache License 2.0 that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package naming
|
||||
|
||||
// NamingStrategy naming strategy interface
|
||||
type NamingStrategy interface {
|
||||
Naming(string) string
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
// Copyright 2020 Michael Li <alimy@gility.net>. All rights reserved.
|
||||
// Use of this source code is governed by Apache License 2.0 that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package naming
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestSnakeNamingStrategy_Naming(t *testing.T) {
|
||||
ns := NewSnakeNamingStrategy()
|
||||
for _, cs := range []struct {
|
||||
name string
|
||||
expected string
|
||||
}{
|
||||
{name: "abc", expected: "abc"},
|
||||
{name: "Abc", expected: "abc"},
|
||||
{name: "HostName", expected: "host_name"},
|
||||
{name: "Host_Name", expected: "host_name"},
|
||||
{name: "RESTfulAPI", expected: "res_tful_api"},
|
||||
{name: "HTTPS_API", expected: "https_api"},
|
||||
{name: "PKG_Name", expected: "pkg_name"},
|
||||
{name: "API", expected: "api"},
|
||||
{name: "HTTP", expected: "http"},
|
||||
} {
|
||||
result := ns.Naming(cs.name)
|
||||
if result != cs.expected {
|
||||
t.Errorf("give:%s expected:%s result:%s", cs.name, cs.expected, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimpleNamingStrategy_Naming(t *testing.T) {
|
||||
ns := NewSimpleNamingStrategy()
|
||||
for _, cs := range []struct {
|
||||
name string
|
||||
expected string
|
||||
}{
|
||||
{name: "abc", expected: "abc"},
|
||||
{name: "Abc", expected: "abc"},
|
||||
{name: "HostName", expected: "host_name"},
|
||||
{name: "Host_Name", expected: "host__name"},
|
||||
{name: "RESTfulAPI", expected: "r_e_s_tful_a_p_i"},
|
||||
{name: "HTTPS_API", expected: "h_t_t_p_s__a_p_i"},
|
||||
{name: "PKG_Name", expected: "p_k_g__name"},
|
||||
{name: "API", expected: "a_p_i"},
|
||||
{name: "HTTP", expected: "h_t_t_p"},
|
||||
} {
|
||||
result := ns.Naming(cs.name)
|
||||
if result != cs.expected {
|
||||
t.Errorf("give:%s expected:%s result:%s", cs.name, cs.expected, result)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
// Copyright 2020 Michael Li <alimy@gility.net>. All rights reserved.
|
||||
// Use of this source code is governed by Apache License 2.0 that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package naming
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type simpleNamingStrategy struct {
|
||||
// just empty
|
||||
}
|
||||
|
||||
func (s *simpleNamingStrategy) Naming(name string) string {
|
||||
b := &strings.Builder{}
|
||||
notFirst := false
|
||||
b.Grow(len(name) + 3)
|
||||
for _, r := range name {
|
||||
if unicode.IsUpper(r) {
|
||||
if notFirst {
|
||||
b.WriteRune('_')
|
||||
}
|
||||
b.WriteRune(unicode.ToLower(r))
|
||||
} else {
|
||||
b.WriteRune(r)
|
||||
}
|
||||
notFirst = true
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// NewSimpleNamingStrategy return simple naming strategy instance
|
||||
func NewSimpleNamingStrategy() NamingStrategy {
|
||||
return &simpleNamingStrategy{}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
// Copyright 2020 Michael Li <alimy@gility.net>. All rights reserved.
|
||||
// Use of this source code is governed by Apache License 2.0 that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
package naming
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// snakeNamingStrategy snake naming strategy implement
|
||||
// This implement is inspiration from https://github.com/jingzhu/gorm's naming logic.
|
||||
type snakeNamingStrategy struct {
|
||||
initialismsReplacer *strings.Replacer
|
||||
}
|
||||
|
||||
func (s *snakeNamingStrategy) Naming(name string) string {
|
||||
if name == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
var lastCase, currCase, nextCase, nextNumber bool
|
||||
value := s.initialismsReplacer.Replace(name)
|
||||
buf := bytes.NewBufferString("")
|
||||
lower, upper := false, true
|
||||
for i, v := range value[:len(value)-1] {
|
||||
nextCase = value[i+1] >= 'A' && value[i+1] <= 'Z'
|
||||
nextNumber = value[i+1] >= '0' && value[i+1] <= '9'
|
||||
if i > 0 {
|
||||
if currCase == upper {
|
||||
if lastCase == upper && (nextCase == upper || nextNumber == upper) {
|
||||
buf.WriteRune(v)
|
||||
} else {
|
||||
if value[i-1] != '_' && value[i+1] != '_' {
|
||||
buf.WriteRune('_')
|
||||
}
|
||||
buf.WriteRune(v)
|
||||
}
|
||||
} else {
|
||||
buf.WriteRune(v)
|
||||
if i == len(value)-2 && (nextCase == upper && nextNumber == lower) {
|
||||
buf.WriteRune('_')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
currCase = upper
|
||||
buf.WriteRune(v)
|
||||
}
|
||||
lastCase, currCase = currCase, nextCase
|
||||
}
|
||||
|
||||
buf.WriteByte(value[len(value)-1])
|
||||
res := strings.ToLower(buf.String())
|
||||
return res
|
||||
}
|
||||
|
||||
// NewSnakeNamingStrategy return snake naming strategy instance
|
||||
func NewSnakeNamingStrategy() NamingStrategy {
|
||||
// Copied from golint
|
||||
initialisms := []string{
|
||||
"API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP",
|
||||
"HTTPS", "ID", "IP", "JSON", "LHS", "QPS", "RAM", "RHS", "RPC", "SLA",
|
||||
"SMTP", "SSH", "TLS", "TTL", "UID", "UI", "UUID", "URI", "URL", "UTF8",
|
||||
"VM", "XML", "XSRF", "XSS"}
|
||||
|
||||
var oldnews []string
|
||||
for _, initialism := range initialisms {
|
||||
oldnews = append(oldnews, initialism, strings.Title(strings.ToLower(initialism)))
|
||||
}
|
||||
replacer := strings.NewReplacer(oldnews...)
|
||||
|
||||
return &snakeNamingStrategy{
|
||||
initialismsReplacer: replacer,
|
||||
}
|
||||
}
|
Loading…
Reference in new issue