github.com/jxskiss/gopkg/v2@v2.14.9-0.20240514120614-899f3e7952b4/easy/ezmap/map.go (about)

     1  package ezmap
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"reflect"
     7  	"strconv"
     8  	"time"
     9  
    10  	"github.com/spf13/cast"
    11  	"gopkg.in/yaml.v3"
    12  )
    13  
    14  // Map is a map of string key and any value.
    15  // It provides many useful methods to work with map[string]any.
    16  type Map map[string]any
    17  
    18  // NewMap returns a new initialized Map.
    19  func NewMap() Map {
    20  	return make(Map)
    21  }
    22  
    23  // MarshalJSON implements the json.Marshaler interface.
    24  func (p Map) MarshalJSON() ([]byte, error) {
    25  	x := map[string]any(p)
    26  	return json.Marshal(x)
    27  }
    28  
    29  // MarshalJSONPretty returns its marshaled data as `[]byte` with
    30  // indentation using two spaces.
    31  func (p Map) MarshalJSONPretty() ([]byte, error) {
    32  	x := map[string]any(p)
    33  	return json.MarshalIndent(x, "", "  ")
    34  }
    35  
    36  // UnmarshalJSON implements the json.Unmarshaler interface.
    37  func (p *Map) UnmarshalJSON(data []byte) error {
    38  	x := (*map[string]any)(p)
    39  	return json.Unmarshal(data, x)
    40  }
    41  
    42  // MarshalYAML implements the [yaml.Marshaler] interface.
    43  func (p Map) MarshalYAML() (any, error) {
    44  	return (map[string]any)(p), nil
    45  }
    46  
    47  // UnmarshalYAML implements the [yaml.Unmarshaler] interface.
    48  func (p *Map) UnmarshalYAML(value *yaml.Node) error {
    49  	x := (*map[string]any)(p)
    50  	return value.Decode(x)
    51  }
    52  
    53  // Size returns the number of elements in the map.
    54  func (p Map) Size() int {
    55  	return len(p)
    56  }
    57  
    58  // Set is used to store a new key/value pair exclusively in the map.
    59  // It also lazily initializes the map if it was not used previously.
    60  func (p *Map) Set(key string, value any) {
    61  	if *p == nil {
    62  		*p = make(Map)
    63  	}
    64  	(*p)[key] = value
    65  }
    66  
    67  // Get returns the value for the given key, ie: (value, true).
    68  // If the value does not exist it returns (nil, false)
    69  func (p Map) Get(key string) (value any, exists bool) {
    70  	value, exists = p[key]
    71  	return
    72  }
    73  
    74  // GetOr returns the value for the given key if it exists in the map,
    75  // else it returns the default value.
    76  func (p Map) GetOr(key string, defaultVal any) (value any) {
    77  	value, exists := p[key]
    78  	if exists {
    79  		return value
    80  	}
    81  	return defaultVal
    82  }
    83  
    84  // MustGet returns the value for the given key if it exists, otherwise it panics.
    85  func (p Map) MustGet(key string) any {
    86  	if val, ok := p[key]; ok {
    87  		return val
    88  	}
    89  	panic(fmt.Sprintf("key %q not exists", key))
    90  }
    91  
    92  // GetString returns the value associated with the key as a string.
    93  func (p Map) GetString(key string) string {
    94  	val, ok := p[key]
    95  	if ok {
    96  		return cast.ToString(val)
    97  	}
    98  	return ""
    99  }
   100  
   101  // GetBytes returns the value associated with the key as bytes.
   102  func (p Map) GetBytes(key string) []byte {
   103  	v := p[key]
   104  	if val, ok := v.([]byte); ok {
   105  		return val
   106  	}
   107  	if val, ok := v.(string); ok {
   108  		return []byte(val)
   109  	}
   110  	return nil
   111  }
   112  
   113  // GetBool returns the value associated with the key as a boolean value.
   114  func (p Map) GetBool(key string) bool {
   115  	val, ok := p[key]
   116  	if ok {
   117  		return cast.ToBool(val)
   118  	}
   119  	return false
   120  }
   121  
   122  // GetInt returns the value associated with the key as an int.
   123  func (p Map) GetInt(key string) int {
   124  	val, ok := p[key]
   125  	if ok {
   126  		return cast.ToInt(val)
   127  	}
   128  	return 0
   129  }
   130  
   131  // GetInt32 returns the value associated with the key as an int32.
   132  func (p Map) GetInt32(key string) int32 {
   133  	val, ok := p[key]
   134  	if ok {
   135  		return cast.ToInt32(val)
   136  	}
   137  	return 0
   138  }
   139  
   140  // GetInt64 returns the value associated with the key as an int64.
   141  func (p Map) GetInt64(key string) int64 {
   142  	val, ok := p[key]
   143  	if ok {
   144  		return cast.ToInt64(val)
   145  	}
   146  	return 0
   147  }
   148  
   149  // GetUint returns the value associated with the key as an uint.
   150  func (p Map) GetUint(key string) uint {
   151  	val, ok := p[key]
   152  	if ok {
   153  		return cast.ToUint(val)
   154  	}
   155  	return 0
   156  }
   157  
   158  // GetUint32 returns the value associated with the key as an uint32.
   159  func (p Map) GetUint32(key string) uint32 {
   160  	val, ok := p[key]
   161  	if ok {
   162  		return cast.ToUint32(val)
   163  	}
   164  	return 0
   165  }
   166  
   167  // GetUint64 returns the value associated with the key as an uint64.
   168  func (p Map) GetUint64(key string) uint64 {
   169  	val, ok := p[key]
   170  	if ok {
   171  		return cast.ToUint64(val)
   172  	}
   173  	return 0
   174  }
   175  
   176  // GetFloat returns the value associated with the key as a float64.
   177  func (p Map) GetFloat(key string) float64 {
   178  	val, ok := p[key]
   179  	if ok {
   180  		switch v := val.(type) {
   181  		case float64:
   182  			return v
   183  		case json.Number:
   184  			num, _ := v.Float64()
   185  			return num
   186  		case string:
   187  			num, _ := strconv.ParseFloat(v, 64)
   188  			return num
   189  		}
   190  		typ := reflect.TypeOf(val)
   191  		switch typ.Kind() {
   192  		case reflect.Float32, reflect.Float64:
   193  			return reflect.ValueOf(val).Float()
   194  		}
   195  		if intVal := p.GetInt(key); intVal != 0 {
   196  			return float64(intVal)
   197  		}
   198  	}
   199  	return 0
   200  }
   201  
   202  // GetTime returns the value associated with the key as time.
   203  func (p Map) GetTime(key string) time.Time {
   204  	val, _ := p[key].(time.Time)
   205  	return val
   206  }
   207  
   208  // GetDuration returns the value associated with the key as a duration.
   209  func (p Map) GetDuration(key string) time.Duration {
   210  	val, ok := p[key]
   211  	if ok {
   212  		switch v := val.(type) {
   213  		case time.Duration:
   214  			return v
   215  		case int64:
   216  			return time.Duration(v)
   217  		case string:
   218  			d, err := time.ParseDuration(v)
   219  			if err == nil {
   220  				return d
   221  			}
   222  		}
   223  	}
   224  	return 0
   225  }
   226  
   227  // GetInt64s returns the value associated with the key as a slice of int64.
   228  func (p Map) GetInt64s(key string) []int64 {
   229  	val, ok := p[key]
   230  	if ok {
   231  		switch val := val.(type) {
   232  		case []int64:
   233  			return val
   234  		}
   235  	}
   236  	return nil
   237  }
   238  
   239  // GetInt32s returns the value associated with the key as a slice of int32.
   240  func (p Map) GetInt32s(key string) []int32 {
   241  	val, ok := p[key]
   242  	if ok {
   243  		switch val := val.(type) {
   244  		case []int32:
   245  			return val
   246  		}
   247  	}
   248  	return nil
   249  }
   250  
   251  // GetStrings returns the value associated with the key as a slice of strings.
   252  func (p Map) GetStrings(key string) []string {
   253  	val, ok := p[key]
   254  	if ok {
   255  		switch val := val.(type) {
   256  		case []string:
   257  			return val
   258  		default:
   259  			return cast.ToStringSlice(val)
   260  		}
   261  	}
   262  	return nil
   263  }
   264  
   265  // GetSlice returns the value associated with the key as a slice.
   266  // It returns nil if key does not present in Map or the value's type
   267  // is not a slice.
   268  func (p Map) GetSlice(key string) any {
   269  	val, ok := p[key]
   270  	if !ok || reflect.TypeOf(val).Kind() != reflect.Slice {
   271  		return nil
   272  	}
   273  	return val
   274  }
   275  
   276  // GetMap returns the value associated with the key as a Map (map[string]any).
   277  func (p Map) GetMap(key string) Map {
   278  	val, ok := p[key]
   279  	if ok {
   280  		switch val := val.(type) {
   281  		case Map:
   282  			return val
   283  		case map[string]any:
   284  			return val
   285  		}
   286  	}
   287  	return nil
   288  }
   289  
   290  // GetStringMap returns the value associated with the key as a map of (map[string]string).
   291  func (p Map) GetStringMap(key string) map[string]string {
   292  	if val, ok := p[key].(map[string]string); ok {
   293  		return val
   294  	}
   295  	return nil
   296  }
   297  
   298  // Iterate iterates the map in unspecified order, the given function fn
   299  // will be called for each key value pair.
   300  // The iteration can be aborted by returning a non-zero value from fn.
   301  func (p Map) Iterate(fn func(k string, v any) int) {
   302  	for k, v := range p {
   303  		if fn(k, v) != 0 {
   304  			return
   305  		}
   306  	}
   307  }
   308  
   309  // Merge merges key values from another map.
   310  func (p *Map) Merge(other map[string]any) {
   311  	if *p == nil {
   312  		*p = make(Map)
   313  	}
   314  	for k, v := range other {
   315  		(*p)[k] = v
   316  	}
   317  }