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 }