Files
stash/internal/manager/config/map.go
CJ 9264c15540 Customize recommendations (#2592)
* refactored common code in recommendation row
* Implement front page options in config
* Allow customisation from front page
* Rename recommendations to front page
* Add generic UI settings
* Support adding premade filters

Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
2022-06-14 10:34:04 +10:00

87 lines
1.9 KiB
Go

package config
import (
"bytes"
"unicode"
"github.com/spf13/cast"
)
// HACK: viper changes map keys to case insensitive values, so the workaround is to
// convert the map to use snake-case keys
// toSnakeCase converts a string to snake_case
// NOTE: a double capital will be converted in a way that will yield a different result
// when converted back to camel case.
// For example: someIDs => some_ids => someIds
func toSnakeCase(v string) string {
var buf bytes.Buffer
underscored := false
for i, c := range v {
if !underscored && unicode.IsUpper(c) && i > 0 {
buf.WriteByte('_')
underscored = true
} else {
underscored = false
}
buf.WriteRune(unicode.ToLower(c))
}
return buf.String()
}
func fromSnakeCase(v string) string {
var buf bytes.Buffer
cap := false
for i, c := range v {
switch {
case c == '_' && i > 0:
cap = true
case cap:
buf.WriteRune(unicode.ToUpper(c))
cap = false
default:
buf.WriteRune(c)
}
}
return buf.String()
}
// copyAndInsensitiviseMap behaves like insensitiviseMap, but creates a copy of
// any map it makes case insensitive.
func toSnakeCaseMap(m map[string]interface{}) map[string]interface{} {
nm := make(map[string]interface{})
for key, val := range m {
adjKey := toSnakeCase(key)
switch v := val.(type) {
case map[interface{}]interface{}:
nm[adjKey] = toSnakeCaseMap(cast.ToStringMap(v))
case map[string]interface{}:
nm[adjKey] = toSnakeCaseMap(v)
default:
nm[adjKey] = v
}
}
return nm
}
func fromSnakeCaseMap(m map[string]interface{}) map[string]interface{} {
nm := make(map[string]interface{})
for key, val := range m {
adjKey := fromSnakeCase(key)
switch v := val.(type) {
case map[interface{}]interface{}:
nm[adjKey] = fromSnakeCaseMap(cast.ToStringMap(v))
case map[string]interface{}:
nm[adjKey] = fromSnakeCaseMap(v)
default:
nm[adjKey] = v
}
}
return nm
}