Created
Some checks failed
Go / build (push) Failing after 7s

This commit is contained in:
scheibling
2025-04-08 19:16:39 +02:00
commit b4eb50ab55
63 changed files with 7333 additions and 0 deletions

70
keyx/key.go Normal file
View File

@@ -0,0 +1,70 @@
package keyx
import (
"reflect"
"sort"
"strconv"
"strings"
)
// Generate 生成 Key
func Generate(values ...interface{}) string {
var sb strings.Builder
for _, value := range values {
v := reflect.ValueOf(value)
switch v.Kind() {
case reflect.String:
if v.Len() != 0 {
sb.WriteString(v.String())
}
case reflect.Bool:
sb.WriteString(strconv.FormatBool(v.Bool()))
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if b, ok := value.(rune); ok {
sb.WriteRune(b)
} else {
sb.WriteString(strconv.FormatInt(v.Int(), 10))
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
if b, ok := value.(byte); ok {
sb.WriteByte(b)
} else {
sb.WriteString(strconv.FormatUint(v.Uint(), 10))
}
case reflect.Float32, reflect.Float64:
sb.WriteString(strconv.FormatFloat(v.Float(), 'f', -1, 64))
case reflect.Map:
keys := make([]string, len(v.MapKeys()))
i := 0
for _, mv := range v.MapKeys() {
keys[i] = mv.String()
i++
}
sort.Strings(keys)
interfaces := make([]interface{}, 0)
for k := range keys {
interfaces = append(interfaces, keys[k], v.MapIndex(reflect.ValueOf(keys[k])).Interface())
}
sb.WriteString(Generate(interfaces...))
case reflect.Slice, reflect.Array:
interfaces := make([]interface{}, 0)
for i := 0; i < v.Len(); i++ {
interfaces = append(interfaces, v.Index(i).Interface())
}
sb.WriteString(Generate(interfaces...))
case reflect.Struct:
kv := map[string]interface{}{}
t := reflect.TypeOf(value)
if t.Name() != "" {
sb.WriteString(t.Name() + ":")
}
for k := 0; k < t.NumField(); k++ {
kv[t.Field(k).Name] = v.Field(k).Interface()
}
sb.WriteString(Generate(kv))
default:
sb.WriteString(v.String())
}
}
return sb.String()
}

63
keyx/key_test.go Normal file
View File

@@ -0,0 +1,63 @@
package keyx
import (
"testing"
)
func TestGenerate(t *testing.T) {
type User struct {
ID int
Name string
}
type testCase struct {
Number int
Values interface{}
Key string
}
b1 := []byte("")
b2 := []byte("abc")
testCases := []testCase{
{1, []interface{}{1, 2, 3}, "123"},
{2, []interface{}{0, -1, 2, 3}, "0-123"},
{3, []interface{}{1.1, 2.12, 3.123}, "1.12.123.123"},
{4, []interface{}{1.1, 2.12, 3.123}, "1.12.123.123"},
{5, []interface{}{"a", "b", "c"}, "abc"},
{6, []interface{}{"a", "b", "c", 1, 2, 3}, "abc123"},
{7, []interface{}{true, true, false, false}, "truetruefalsefalse"},
{8, []interface{}{[]int{1, 2, 3}}, "123"},
{9, []interface{}{[...]int{1, 2, 3, 4}}, "1234"},
{10, []interface{}{struct {
Username string
Age int
}{}}, "Age0Username"},
{11, []interface{}{struct {
Username string
Age int
}{"John", 12}}, "Age12UsernameJohn"},
{12, []interface{}{User{
ID: 1,
Name: "John",
}}, "User:ID1NameJohn"},
// byte
{13, []interface{}{b1, b2}, "abc"},
// rune
{14, []interface{}{'a', 'b', 'c'}, "abc"},
{15, []map[string]string{{"k1": "v1", "k2": "v2"}}, "k1v1k2v2"},
}
for _, tc := range testCases {
key := Generate(tc.Values)
if key != tc.Key {
t.Errorf("%d: except%s actual%s", tc.Number, tc.Key, key)
}
}
}
func BenchmarkGenerate(b *testing.B) {
for i := 0; i < b.N; i++ {
Generate([]interface{}{struct {
Username string
Age int
}{"John", 12}})
}
}