mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-02 21:23:20 -04:00
The goutil that OpenCloud currently uses is one version from the release that adds FreeBSD support, this now compiles successfully on FreeBSD.
360 lines
7.2 KiB
Go
360 lines
7.2 KiB
Go
package maputil
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/gookit/goutil/arrutil"
|
|
"github.com/gookit/goutil/internal/comfunc"
|
|
"github.com/gookit/goutil/mathutil"
|
|
"github.com/gookit/goutil/strutil"
|
|
)
|
|
|
|
// Map alias of Data
|
|
type Map = Data
|
|
|
|
// Data alias of map[string]any
|
|
type Data map[string]any
|
|
|
|
// Has value on the data map
|
|
func (d Data) Has(key string) bool {
|
|
_, ok := d.GetByPath(key)
|
|
return ok
|
|
}
|
|
|
|
// IsEmpty if the data map
|
|
func (d Data) IsEmpty() bool {
|
|
return len(d) == 0
|
|
}
|
|
|
|
//
|
|
// endregion
|
|
// region T: set value(s)
|
|
//
|
|
|
|
// Set value to the data map
|
|
func (d Data) Set(key string, val any) {
|
|
d[key] = val
|
|
}
|
|
|
|
// SetByPath sets a value in the map.
|
|
// Supports dot syntax to set deep values.
|
|
//
|
|
// Example:
|
|
//
|
|
// d.SetByPath("name.first", "Mat")
|
|
func (d Data) SetByPath(path string, value any) error {
|
|
if path == "" {
|
|
return nil
|
|
}
|
|
return d.SetByKeys(strings.Split(path, KeySepStr), value)
|
|
}
|
|
|
|
// SetByKeys sets a value in the map by path keys.
|
|
// Supports dot syntax to set deep values.
|
|
//
|
|
// Example:
|
|
//
|
|
// d.SetByKeys([]string{"name", "first"}, "Mat")
|
|
func (d Data) SetByKeys(keys []string, value any) error {
|
|
kln := len(keys)
|
|
if kln == 0 {
|
|
return nil
|
|
}
|
|
|
|
// special handle d is empty.
|
|
if len(d) == 0 {
|
|
if kln == 1 {
|
|
d.Set(keys[0], value)
|
|
} else {
|
|
d.Set(keys[0], MakeByKeys(keys[1:], value))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
return SetByKeys((*map[string]any)(&d), keys, value)
|
|
// It's ok, but use `func (d *Data)`
|
|
// return SetByKeys((*map[string]any)(d), keys, value)
|
|
}
|
|
|
|
//
|
|
// endregion
|
|
// region T: read value(s)
|
|
//
|
|
|
|
// Value get from the data map
|
|
func (d Data) Value(key string) (any, bool) {
|
|
val, ok := d.GetByPath(key)
|
|
return val, ok
|
|
}
|
|
|
|
// Get value from the data map.
|
|
// Supports dot syntax to get deep values. eg: top.sub
|
|
func (d Data) Get(key string) any {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return val
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// One get value from the data by multi paths. will return first founded value
|
|
func (d Data) One(keys ...string) any {
|
|
if val, ok := d.TryOne(keys...); ok {
|
|
return val
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// TryOne get value from the data by multi paths. will return first founded value
|
|
func (d Data) TryOne(keys ...string) (any, bool) {
|
|
for _, path := range keys {
|
|
if val, ok := d.GetByPath(path); ok {
|
|
return val, true
|
|
}
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
// GetByPath get value from the data map by path. eg: top.sub
|
|
// Supports dot syntax to get deep values.
|
|
func (d Data) GetByPath(path string) (any, bool) {
|
|
if val, ok := d[path]; ok {
|
|
return val, true
|
|
}
|
|
|
|
// is a key path.
|
|
if strings.ContainsRune(path, '.') {
|
|
val, ok := GetByPath(path, d)
|
|
if ok {
|
|
return val, true
|
|
}
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
// Default get value from the data map with default value
|
|
func (d Data) Default(key string, def any) any {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return val
|
|
}
|
|
return def
|
|
}
|
|
|
|
// Int value get, or default value
|
|
func (d Data) Int(key string, defVal ...int) int {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return mathutil.SafeInt(val)
|
|
}
|
|
if len(defVal) > 0 {
|
|
return defVal[0]
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// Int64 value get, or default value
|
|
func (d Data) Int64(key string, defVal ...int64) int64 {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return mathutil.SafeInt64(val)
|
|
}
|
|
if len(defVal) > 0 {
|
|
return defVal[0]
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// Uint value get, or default value
|
|
func (d Data) Uint(key string, defVal ...uint) uint {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return mathutil.QuietUint(val)
|
|
}
|
|
if len(defVal) > 0 {
|
|
return defVal[0]
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// Uint16 value get, or default value
|
|
func (d Data) Uint16(key string, defVal ...uint16) uint16 {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return uint16(mathutil.SafeUint(val))
|
|
}
|
|
|
|
if len(defVal) > 0 {
|
|
return defVal[0]
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// Uint64 value get, or default value
|
|
func (d Data) Uint64(key string, defVal ...uint64) uint64 {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return mathutil.QuietUint64(val)
|
|
}
|
|
if len(defVal) > 0 {
|
|
return defVal[0]
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// Str value gets by key, or default value
|
|
func (d Data) Str(key string, defVal ...string) string {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return strutil.SafeString(val)
|
|
}
|
|
if len(defVal) > 0 {
|
|
return defVal[0]
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// StrOne value gets by multi keys, will return first value
|
|
func (d Data) StrOne(keys ...string) string {
|
|
for _, key := range keys {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return strutil.SafeString(val)
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// Bool value get
|
|
func (d Data) Bool(key string) bool {
|
|
val, ok := d.GetByPath(key)
|
|
if !ok {
|
|
return false
|
|
}
|
|
return comfunc.Bool(val)
|
|
}
|
|
|
|
// BoolOne value gets from multi keys, return first value
|
|
func (d Data) BoolOne(keys ...string) bool {
|
|
for _, key := range keys {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return comfunc.Bool(val)
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// StringsOne get []string value by multi keys, return first founded value
|
|
func (d Data) StringsOne(keys ...string) []string {
|
|
for _, key := range keys {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return arrutil.AnyToStrings(val)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Strings get []string value by key
|
|
func (d Data) Strings(key string) []string {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return arrutil.AnyToStrings(val)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// StrSplit get strings by split string value
|
|
func (d Data) StrSplit(key, sep string) []string {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return strings.Split(strutil.SafeString(val), sep)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// StringsByStr value gets by key, will split string value by ","
|
|
func (d Data) StringsByStr(key string) []string {
|
|
return d.StrSplit(key, ",")
|
|
}
|
|
|
|
// StrMap get map[string]string value
|
|
func (d Data) StrMap(key string) map[string]string {
|
|
return d.StringMap(key)
|
|
}
|
|
|
|
// StringMap get map[string]string value
|
|
func (d Data) StringMap(key string) map[string]string {
|
|
val, ok := d.GetByPath(key)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
switch tv := val.(type) {
|
|
case map[string]string:
|
|
return tv
|
|
case map[string]any:
|
|
return ToStringMap(tv)
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// Sub get sub value(map[string]any) as new Data
|
|
func (d Data) Sub(key string) Data {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return d.toAnyMap(val)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// AnyMap get sub value as map[string]any
|
|
func (d Data) AnyMap(key string) map[string]any {
|
|
if val, ok := d.GetByPath(key); ok {
|
|
return d.toAnyMap(val)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// AnyMap get sub value as map[string]any
|
|
func (d Data) toAnyMap(val any) map[string]any {
|
|
switch tv := val.(type) {
|
|
case map[string]string:
|
|
return ToAnyMap(tv)
|
|
case map[string]any:
|
|
return tv
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// Slice get []any value from data map
|
|
func (d Data) Slice(key string) ([]any, error) {
|
|
val, ok := d.GetByPath(key)
|
|
if !ok {
|
|
return nil, nil
|
|
}
|
|
return arrutil.AnyToSlice(val)
|
|
}
|
|
|
|
// Keys of the data map
|
|
func (d Data) Keys() []string {
|
|
keys := make([]string, 0, len(d))
|
|
for k := range d {
|
|
keys = append(keys, k)
|
|
}
|
|
return keys
|
|
}
|
|
|
|
// ToStringMap convert to map[string]string
|
|
func (d Data) ToStringMap() map[string]string {
|
|
return ToStringMap(d)
|
|
}
|
|
|
|
// String data to string
|
|
func (d Data) String() string {
|
|
return ToString(d)
|
|
}
|
|
|
|
// Load other data to current data map
|
|
func (d Data) Load(sub map[string]any) {
|
|
for name, val := range sub {
|
|
d[name] = val
|
|
}
|
|
}
|
|
|
|
// LoadSMap to data
|
|
func (d Data) LoadSMap(smp map[string]string) {
|
|
for name, val := range smp {
|
|
d[name] = val
|
|
}
|
|
}
|