mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-02 19:20:08 -05:00
Bumps [github.com/gookit/config/v2](https://github.com/gookit/config) from 2.2.6 to 2.2.7. - [Release notes](https://github.com/gookit/config/releases) - [Commits](https://github.com/gookit/config/compare/v2.2.6...v2.2.7) --- updated-dependencies: - dependency-name: github.com/gookit/config/v2 dependency-version: 2.2.7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
192 lines
3.9 KiB
Go
192 lines
3.9 KiB
Go
// Package maputil provide map data util functions. eg: convert, sub-value get, simple merge
|
|
package maputil
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
|
|
"github.com/gookit/goutil/arrutil"
|
|
)
|
|
|
|
// Key, value sep char consts
|
|
const (
|
|
ValSepStr = ","
|
|
ValSepChar = ','
|
|
KeySepStr = "."
|
|
KeySepChar = '.'
|
|
)
|
|
|
|
// SimpleMerge simple merge two data map by string key. will merge the src to dst map
|
|
func SimpleMerge(src, dst map[string]any) map[string]any {
|
|
if len(src) == 0 {
|
|
return dst
|
|
}
|
|
if len(dst) == 0 {
|
|
return src
|
|
}
|
|
|
|
for key, val := range src {
|
|
if mp, ok := val.(map[string]any); ok {
|
|
if dmp, ok := dst[key].(map[string]any); ok {
|
|
dst[key] = SimpleMerge(mp, dmp)
|
|
continue
|
|
}
|
|
}
|
|
|
|
// simple merge
|
|
dst[key] = val
|
|
}
|
|
return dst
|
|
}
|
|
|
|
// Merge1level merge multi any map[string]any data. only merge one level data.
|
|
func Merge1level(mps ...map[string]any) map[string]any {
|
|
newMp := make(map[string]any)
|
|
for _, mp := range mps {
|
|
for k, v := range mp {
|
|
newMp[k] = v
|
|
}
|
|
}
|
|
return newMp
|
|
}
|
|
|
|
// func DeepMerge(src, dst map[string]any, deep int) map[string]any { TODO
|
|
// }
|
|
|
|
// MergeSMap simple merge two string map. merge src to dst map
|
|
func MergeSMap(src, dst map[string]string, ignoreCase bool) map[string]string {
|
|
return MergeStringMap(src, dst, ignoreCase)
|
|
}
|
|
|
|
// MergeStrMap simple merge two string map. merge src to dst map
|
|
func MergeStrMap(src, dst map[string]string) map[string]string {
|
|
return MergeStringMap(src, dst, false)
|
|
}
|
|
|
|
// MergeStringMap simple merge two string map. merge src to dst map
|
|
func MergeStringMap(src, dst map[string]string, ignoreCase bool) map[string]string {
|
|
if len(src) == 0 {
|
|
return dst
|
|
}
|
|
if len(dst) == 0 {
|
|
return src
|
|
}
|
|
|
|
for k, v := range src {
|
|
if ignoreCase {
|
|
k = strings.ToLower(k)
|
|
}
|
|
dst[k] = v
|
|
}
|
|
return dst
|
|
}
|
|
|
|
// MergeMultiSMap quick merge multi string-map data.
|
|
func MergeMultiSMap(mps ...map[string]string) map[string]string {
|
|
newMp := make(map[string]string)
|
|
for _, mp := range mps {
|
|
for k, v := range mp {
|
|
newMp[k] = v
|
|
}
|
|
}
|
|
return newMp
|
|
}
|
|
|
|
// MergeL2StrMap merge multi level2 string-map data. The back map covers the front.
|
|
func MergeL2StrMap(mps ...map[string]map[string]string) map[string]map[string]string {
|
|
newMp := make(map[string]map[string]string)
|
|
for _, mp := range mps {
|
|
for k, v := range mp {
|
|
// merge level 2 value
|
|
if oldV, ok := newMp[k]; ok {
|
|
for k1, v1 := range v {
|
|
oldV[k1] = v1
|
|
}
|
|
newMp[k] = oldV
|
|
} else {
|
|
newMp[k] = v
|
|
}
|
|
}
|
|
}
|
|
return newMp
|
|
}
|
|
|
|
// FilterSMap filter empty elem for the string map.
|
|
func FilterSMap(sm map[string]string) map[string]string {
|
|
for key, val := range sm {
|
|
if val == "" {
|
|
delete(sm, key)
|
|
}
|
|
}
|
|
return sm
|
|
}
|
|
|
|
// MakeByPath build new value by key names
|
|
//
|
|
// Example:
|
|
//
|
|
// "site.info"
|
|
// ->
|
|
// map[string]any {
|
|
// site: {info: val}
|
|
// }
|
|
//
|
|
// // case 2, last key is slice:
|
|
// "site.tags[1]"
|
|
// ->
|
|
// map[string]any {
|
|
// site: {tags: [val]}
|
|
// }
|
|
func MakeByPath(path string, val any) (mp map[string]any) {
|
|
return MakeByKeys(strings.Split(path, KeySepStr), val)
|
|
}
|
|
|
|
// MakeByKeys build new value by key names
|
|
//
|
|
// Example:
|
|
//
|
|
// // case 1:
|
|
// []string{"site", "info"}
|
|
// ->
|
|
// map[string]any {
|
|
// site: {info: val}
|
|
// }
|
|
//
|
|
// // case 2, last key is slice:
|
|
// []string{"site", "tags[1]"}
|
|
// ->
|
|
// map[string]any {
|
|
// site: {tags: [val]}
|
|
// }
|
|
func MakeByKeys(keys []string, val any) (mp map[string]any) {
|
|
size := len(keys)
|
|
|
|
// if last key contains slice index, make slice wrap the val
|
|
lastKey := keys[size-1]
|
|
if newK, idx, ok := parseArrKeyIndex(lastKey); ok {
|
|
// valTyp := reflect.TypeOf(val)
|
|
sliTyp := reflect.SliceOf(reflect.TypeOf(val))
|
|
sliVal := reflect.MakeSlice(sliTyp, idx+1, idx+1)
|
|
sliVal.Index(idx).Set(reflect.ValueOf(val))
|
|
|
|
// update val and last key
|
|
val = sliVal.Interface()
|
|
keys[size-1] = newK
|
|
}
|
|
|
|
if size == 1 {
|
|
return map[string]any{keys[0]: val}
|
|
}
|
|
|
|
// multi nodes
|
|
arrutil.Reverse(keys)
|
|
for _, p := range keys {
|
|
if mp == nil {
|
|
mp = map[string]any{p: val}
|
|
} else {
|
|
mp = map[string]any{p: mp}
|
|
}
|
|
}
|
|
return
|
|
}
|