зеркало из https://github.com/github/vitess-gh.git
Create new snake_case_converter.
Add a conversion function from - to _ and add unit test. Signed-off-by: Maggie Zhou <mzhou@slack-corp.com>
This commit is contained in:
Родитель
3fa5a10e4d
Коммит
629294d4ee
|
@ -22,32 +22,6 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetSnakeName calls toSnakeName on the passed in string. It produces
|
|
||||||
// a snake-cased name from the provided camel-cased name.
|
|
||||||
// It memoizes the transformation and returns the stored result if available.
|
|
||||||
func GetSnakeName(name string) string {
|
|
||||||
return toSnakeCase(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// toSnakeCase produces a monitoring compliant name from the original.
|
|
||||||
// For systems (like Prometheus) that ask for snake-case names.
|
|
||||||
// It converts CamelCase to camel_case, and CAMEL_CASE to camel_case.
|
|
||||||
// For numbers, it converts 0.5 to v0_5.
|
|
||||||
func toSnakeCase(name string) (hyphenated string) {
|
|
||||||
memoizer.Lock()
|
|
||||||
defer memoizer.Unlock()
|
|
||||||
if hyphenated = memoizer.memo[name]; hyphenated != "" {
|
|
||||||
return hyphenated
|
|
||||||
}
|
|
||||||
hyphenated = name
|
|
||||||
for _, converter := range snakeConverters {
|
|
||||||
hyphenated = converter.re.ReplaceAllString(hyphenated, converter.repl)
|
|
||||||
}
|
|
||||||
hyphenated = strings.ToLower(hyphenated)
|
|
||||||
memoizer.memo[name] = hyphenated
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// toKebabCase produces a monitoring compliant name from the
|
// toKebabCase produces a monitoring compliant name from the
|
||||||
// original. It converts CamelCase to camel-case,
|
// original. It converts CamelCase to camel-case,
|
||||||
// and CAMEL_CASE to camel-case. For numbers, it
|
// and CAMEL_CASE to camel-case. For numbers, it
|
||||||
|
@ -79,17 +53,6 @@ var kebabConverters = []struct {
|
||||||
{regexp.MustCompile("\\."), "_"},
|
{regexp.MustCompile("\\."), "_"},
|
||||||
}
|
}
|
||||||
|
|
||||||
var snakeConverters = []struct {
|
|
||||||
re *regexp.Regexp
|
|
||||||
repl string
|
|
||||||
}{
|
|
||||||
// example: LC -> L_C (e.g. CamelCase -> Camel_Case).
|
|
||||||
{regexp.MustCompile("([a-z])([A-Z])"), "${1}_${2}"},
|
|
||||||
// example: CCa -> C_Ca (e.g. CCamel -> C_Camel).
|
|
||||||
{regexp.MustCompile("([A-Z])([A-Z][a-z])"), "${1}_${2}"},
|
|
||||||
{regexp.MustCompile("\\."), "_"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var memoizer = memoizerType{
|
var memoizer = memoizerType{
|
||||||
memo: make(map[string]string),
|
memo: make(map[string]string),
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
Copyright 2018 The Vitess Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stats
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetSnakeName calls toSnakeName on the passed in string. It produces
|
||||||
|
// a snake-cased name from the provided camel-cased name.
|
||||||
|
// It memoizes the transformation and returns the stored result if available.
|
||||||
|
func GetSnakeName(name string) string {
|
||||||
|
return toSnakeCase(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// toSnakeCase produces a monitoring compliant name from the original.
|
||||||
|
// For systems (like Prometheus) that ask for snake-case names.
|
||||||
|
// It converts CamelCase to camel_case, and CAMEL_CASE to camel_case.
|
||||||
|
// For numbers, it converts 0.5 to v0_5.
|
||||||
|
func toSnakeCase(name string) (hyphenated string) {
|
||||||
|
snakeMemoizer.Lock()
|
||||||
|
defer snakeMemoizer.Unlock()
|
||||||
|
if hyphenated = snakeMemoizer.memo[name]; hyphenated != "" {
|
||||||
|
return hyphenated
|
||||||
|
}
|
||||||
|
hyphenated = name
|
||||||
|
for _, converter := range snakeConverters {
|
||||||
|
hyphenated = converter.re.ReplaceAllString(hyphenated, converter.repl)
|
||||||
|
}
|
||||||
|
hyphenated = strings.ToLower(hyphenated)
|
||||||
|
snakeMemoizer.memo[name] = hyphenated
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var snakeConverters = []struct {
|
||||||
|
re *regexp.Regexp
|
||||||
|
repl string
|
||||||
|
}{
|
||||||
|
// example: LC -> L_C (e.g. CamelCase -> Camel_Case).
|
||||||
|
{regexp.MustCompile("([a-z])([A-Z])"), "${1}_${2}"},
|
||||||
|
// example: CCa -> C_Ca (e.g. CCamel -> C_Camel).
|
||||||
|
{regexp.MustCompile("([A-Z])([A-Z][a-z])"), "${1}_${2}"},
|
||||||
|
{regexp.MustCompile("\\."), "_"},
|
||||||
|
{regexp.MustCompile("-"), "_"},
|
||||||
|
}
|
||||||
|
|
||||||
|
var snakeMemoizer = memoizerType{
|
||||||
|
memo: make(map[string]string),
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
Copyright 2018 The Vitess Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package stats
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestToSnakeCase(t *testing.T) {
|
||||||
|
var snakeCaseTest = []struct{ input, output string }{
|
||||||
|
{"Camel", "camel"},
|
||||||
|
{"Camel", "camel"},
|
||||||
|
{"CamelCase", "camel_case"},
|
||||||
|
{"CamelCaseAgain", "camel_case_again"},
|
||||||
|
{"CCamel", "c_camel"},
|
||||||
|
{"CCCamel", "cc_camel"},
|
||||||
|
{"CAMEL_CASE", "camel_case"},
|
||||||
|
{"camel-case", "camel_case"},
|
||||||
|
{"0", "0"},
|
||||||
|
{"0.0", "0_0"},
|
||||||
|
{"JSON", "json"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range snakeCaseTest {
|
||||||
|
if got, want := toSnakeCase(tt.input), tt.output; got != want {
|
||||||
|
t.Errorf("want '%s', got '%s'", want, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSnakeMemoize(t *testing.T) {
|
||||||
|
key := "Test"
|
||||||
|
if snakeMemoizer.memo[key] != "" {
|
||||||
|
t.Errorf("want '', got '%s'", snakeMemoizer.memo[key])
|
||||||
|
}
|
||||||
|
toSnakeCase(key)
|
||||||
|
if snakeMemoizer.memo[key] != "test" {
|
||||||
|
t.Errorf("want 'test', got '%s'", snakeMemoizer.memo[key])
|
||||||
|
}
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче