mirror of
https://github.com/foomo/squadron.git
synced 2025-10-16 12:35:42 +00:00
122 lines
1.8 KiB
Go
122 lines
1.8 KiB
Go
package config
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
"slices"
|
|
"sort"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type Map[T any] map[string]T
|
|
|
|
// Trim remove empty entries
|
|
func (m Map[T]) Trim() {
|
|
for key, value := range m {
|
|
val := reflect.ValueOf(value)
|
|
if val.Kind() == reflect.Ptr {
|
|
val = val.Elem()
|
|
}
|
|
|
|
if !val.IsValid() {
|
|
delete(m, key)
|
|
continue
|
|
}
|
|
|
|
if val.IsZero() {
|
|
delete(m, key)
|
|
continue
|
|
}
|
|
|
|
switch val.Kind() { //nolint:exhaustive
|
|
case reflect.Map, reflect.Slice:
|
|
if val.Len() == 0 {
|
|
delete(m, key)
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Keys returns the keys as a sorted list
|
|
func (m Map[T]) Keys() []string {
|
|
if reflect.ValueOf(m).IsZero() {
|
|
return nil
|
|
}
|
|
|
|
ret := make([]string, 0, len(m))
|
|
for key := range m {
|
|
ret = append(ret, key)
|
|
}
|
|
|
|
sort.Strings(ret)
|
|
|
|
return ret
|
|
}
|
|
|
|
// Values returns all values sorted by keys
|
|
func (m Map[T]) Values() []T {
|
|
if len(m) == 0 {
|
|
return nil
|
|
}
|
|
|
|
keys := m.Keys()
|
|
|
|
ret := make([]T, 0, len(keys))
|
|
for i, key := range keys {
|
|
ret[i] = m[key]
|
|
}
|
|
|
|
return ret
|
|
}
|
|
|
|
func (m Map[T]) Filter(keys ...string) error {
|
|
if len(keys) == 0 {
|
|
return nil
|
|
}
|
|
|
|
validKeys := m.Keys()
|
|
for _, key := range keys {
|
|
if !slices.Contains(validKeys, key) {
|
|
return errors.Errorf("key not found: `%s`", key)
|
|
}
|
|
}
|
|
|
|
for key := range m {
|
|
if !slices.Contains(keys, key) {
|
|
delete(m, key)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m Map[T]) FilterFn(handler func(key string, value T) bool) error {
|
|
for key, value := range m {
|
|
if !handler(key, value) {
|
|
delete(m, key)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m Map[T]) Iterate(ctx context.Context, handler func(ctx context.Context, key string, value T) error) error {
|
|
if len(m) == 0 {
|
|
return nil
|
|
}
|
|
|
|
for _, key := range m.Keys() {
|
|
if err := ctx.Err(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := handler(ctx, key, m[key]); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|