Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/gohugoio/hugo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'common/maps/params.go')
-rw-r--r--common/maps/params.go109
1 files changed, 61 insertions, 48 deletions
diff --git a/common/maps/params.go b/common/maps/params.go
index 2d62ad752..ecb63d7a5 100644
--- a/common/maps/params.go
+++ b/common/maps/params.go
@@ -19,76 +19,89 @@ import (
"github.com/spf13/cast"
)
+// Params is a map where all keys are lower case.
+type Params map[string]interface{}
+
+// Get does a lower case and nested search in this map.
+// It will return nil if none found.
+func (p Params) Get(indices ...string) interface{} {
+ v, _, _ := getNested(p, indices)
+ return v
+}
+
+func getNested(m map[string]interface{}, indices []string) (interface{}, string, map[string]interface{}) {
+ if len(indices) == 0 {
+ return nil, "", nil
+ }
+
+ first := indices[0]
+ v, found := m[strings.ToLower(cast.ToString(first))]
+ if !found {
+ return nil, "", nil
+ }
+
+ if len(indices) == 1 {
+ return v, first, m
+ }
+
+ switch m2 := v.(type) {
+ case Params:
+ return getNested(m2, indices[1:])
+ case map[string]interface{}:
+ return getNested(m2, indices[1:])
+ default:
+ return nil, "", nil
+ }
+}
+
// GetNestedParam gets the first match of the keyStr in the candidates given.
// It will first try the exact match and then try to find it as a nested map value,
// using the given separator, e.g. "mymap.name".
// It assumes that all the maps given have lower cased keys.
-func GetNestedParam(keyStr, separator string, candidates ...map[string]interface{}) (interface{}, error) {
+func GetNestedParam(keyStr, separator string, candidates ...Params) (interface{}, error) {
keyStr = strings.ToLower(keyStr)
- lookupFn := func(key string) interface{} {
- for _, m := range candidates {
- if v, ok := m[key]; ok {
- return v
- }
+ // Try exact match first
+ for _, m := range candidates {
+ if v, ok := m[keyStr]; ok {
+ return v, nil
}
-
- return nil
- }
-
- v, _, _, err := GetNestedParamFn(keyStr, separator, lookupFn)
- return v, err
-}
-
-func GetNestedParamFn(keyStr, separator string, lookupFn func(key string) interface{}) (interface{}, string, map[string]interface{}, error) {
- result, _ := traverseDirectParams(keyStr, lookupFn)
- if result != nil {
- return result, keyStr, nil, nil
}
keySegments := strings.Split(keyStr, separator)
- if len(keySegments) == 1 {
- return nil, keyStr, nil, nil
+ for _, m := range candidates {
+ if v := m.Get(keySegments...); v != nil {
+ return v, nil
+ }
}
- return traverseNestedParams(keySegments, lookupFn)
-}
+ return nil, nil
-func traverseDirectParams(keyStr string, lookupFn func(key string) interface{}) (interface{}, error) {
- return lookupFn(keyStr), nil
}
-func traverseNestedParams(keySegments []string, lookupFn func(key string) interface{}) (interface{}, string, map[string]interface{}, error) {
- firstKey, rest := keySegments[0], keySegments[1:]
- result := lookupFn(firstKey)
- if result == nil || len(rest) == 0 {
- return result, firstKey, nil, nil
+func GetNestedParamFn(keyStr, separator string, lookupFn func(key string) interface{}) (interface{}, string, map[string]interface{}, error) {
+ keySegments := strings.Split(strings.ToLower(keyStr), separator)
+ if len(keySegments) == 0 {
+ return nil, "", nil, nil
}
- switch m := result.(type) {
- case map[string]interface{}:
- v, key, owner := traverseParams(rest, m)
- return v, key, owner, nil
- default:
+ first := lookupFn(keySegments[0])
+ if first == nil {
return nil, "", nil, nil
}
-}
-
-func traverseParams(keys []string, m map[string]interface{}) (interface{}, string, map[string]interface{}) {
- // Shift first element off.
- firstKey, rest := keys[0], keys[1:]
- result := m[firstKey]
- // No point in continuing here.
- if result == nil {
- return result, "", nil
+ if len(keySegments) == 1 {
+ return first, keySegments[0], nil, nil
}
- if len(rest) == 0 {
- // That was the last key.
- return result, firstKey, m
+ switch m := first.(type) {
+ case map[string]interface{}:
+ v, key, owner := getNested(m, keySegments[1:])
+ return v, key, owner, nil
+ case Params:
+ v, key, owner := getNested(m, keySegments[1:])
+ return v, key, owner, nil
}
- // That was not the last key.
- return traverseParams(rest, cast.ToStringMap(result))
+ return nil, "", nil, nil
}