mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2025-11-02 15:15:51 +00:00
172 lines
3.1 KiB
Go
172 lines
3.1 KiB
Go
package decoders
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
|
|
"github.com/stoewer/go-strcase"
|
|
)
|
|
|
|
func ParsePath(parts []string, idx int, t reflect.Type) []string {
|
|
if idx >= len(parts) {
|
|
return []string{}
|
|
}
|
|
|
|
if t.Kind() == reflect.Map {
|
|
mapName := strings.ToLower(parts[idx])
|
|
|
|
if idx+1 >= len(parts) {
|
|
return []string{mapName}
|
|
}
|
|
|
|
elemType := t.Elem()
|
|
keyEndIdx := idx + 1
|
|
|
|
if elemType.Kind() == reflect.Struct {
|
|
for i := idx + 1; i < len(parts); i++ {
|
|
found := false
|
|
|
|
for j := 0; j < elemType.NumField(); j++ {
|
|
field := elemType.Field(j)
|
|
if strings.EqualFold(parts[i], field.Name) {
|
|
keyEndIdx = i
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if found {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
keyParts := parts[idx+1 : keyEndIdx]
|
|
keyName := strings.ToLower(strings.Join(keyParts, "_"))
|
|
|
|
rest := ParsePath(parts, keyEndIdx, elemType)
|
|
return append([]string{mapName, keyName}, rest...)
|
|
}
|
|
|
|
if t.Kind() == reflect.Struct {
|
|
for i := 0; i < t.NumField(); i++ {
|
|
field := t.Field(i)
|
|
if strings.EqualFold(parts[idx], field.Name) {
|
|
rest := ParsePath(parts, idx+1, field.Type)
|
|
return append([]string{strings.ToLower(field.Name)}, rest...)
|
|
}
|
|
}
|
|
}
|
|
|
|
return []string{}
|
|
}
|
|
|
|
func normalizeKeys[T any](input map[string]string, root string, sep string) map[string]string {
|
|
knownKeys := getKnownKeys[T]()
|
|
normalized := make(map[string]string)
|
|
|
|
for k, v := range input {
|
|
parts := []string{"tinyauth"}
|
|
|
|
key := strings.ToLower(k)
|
|
key = strings.ReplaceAll(key, sep, "-")
|
|
|
|
suffix := ""
|
|
|
|
for _, known := range knownKeys {
|
|
if strings.HasSuffix(key, known) {
|
|
suffix = known
|
|
break
|
|
}
|
|
}
|
|
|
|
if suffix == "" {
|
|
continue
|
|
}
|
|
|
|
parts = append(parts, root)
|
|
|
|
id := strings.TrimPrefix(key, root+"-")
|
|
id = strings.TrimSuffix(id, "-"+suffix)
|
|
|
|
if id == "" {
|
|
continue
|
|
}
|
|
|
|
parts = append(parts, id)
|
|
parts = append(parts, suffix)
|
|
|
|
final := ""
|
|
|
|
for i, part := range parts {
|
|
if i > 0 {
|
|
final += "."
|
|
}
|
|
final += strcase.LowerCamelCase(part)
|
|
}
|
|
|
|
normalized[final] = v
|
|
}
|
|
|
|
return normalized
|
|
}
|
|
|
|
func getKnownKeys[T any]() []string {
|
|
var keys []string
|
|
var t T
|
|
|
|
v := reflect.ValueOf(t)
|
|
typeOfT := v.Type()
|
|
|
|
for field := range typeOfT.NumField() {
|
|
if typeOfT.Field(field).Tag.Get("field") != "" {
|
|
keys = append(keys, typeOfT.Field(field).Tag.Get("field"))
|
|
continue
|
|
}
|
|
keys = append(keys, strcase.KebabCase(typeOfT.Field(field).Name))
|
|
}
|
|
|
|
return keys
|
|
}
|
|
|
|
func normalizeACLKeys[T any](input map[string]string, root string, sep string) map[string]string {
|
|
normalized := make(map[string]string)
|
|
var t T
|
|
rootType := reflect.TypeOf(t)
|
|
|
|
for k, v := range input {
|
|
parts := strings.Split(strings.ToLower(k), sep)
|
|
|
|
if len(parts) < 2 {
|
|
continue
|
|
}
|
|
|
|
if parts[0] != "tinyauth" {
|
|
continue
|
|
}
|
|
|
|
if parts[1] != root {
|
|
continue
|
|
}
|
|
|
|
if len(parts) > 2 {
|
|
parsedParts := ParsePath(parts[2:], 0, rootType)
|
|
|
|
if len(parsedParts) == 0 {
|
|
continue
|
|
}
|
|
|
|
final := "tinyauth"
|
|
final += "." + root
|
|
|
|
for _, part := range parsedParts {
|
|
final += "." + strcase.LowerCamelCase(part)
|
|
}
|
|
|
|
normalized[final] = v
|
|
}
|
|
}
|
|
|
|
return normalized
|
|
}
|