mar-755-KK / pkg /mapx /mapx.go
aurorax-neo's picture
init
a4468f1
raw
history blame
3.92 kB
package mapx
import (
"encoding/json"
"fmt"
"net/url"
"reflect"
"sort"
"strconv"
"strings"
"time"
)
const dot = "."
type Mapx map[string]interface{}
func (m *Mapx) IsNil(key string) bool {
return m.Get(key) == nil
}
func (m *Mapx) GetString(key string) string {
return fmt.Sprintf("%v", m.Get(key))
}
func (m *Mapx) GetTime(key string) time.Time {
t, _ := time.ParseInLocation(time.RFC3339, m.GetString(key), time.Local)
return t
}
func (m *Mapx) GetInt(key string) int64 {
i, _ := strconv.ParseInt(m.GetString(key), 10, 64)
return i
}
func (m *Mapx) GetFloat(key string) float64 {
f, _ := strconv.ParseFloat(fmt.Sprintf("%v", m.Get(key)), 64)
return f
}
func (m *Mapx) GetBool(key string) bool {
b, _ := strconv.ParseBool(fmt.Sprintf("%v", m.Get(key)))
return b
}
func (m *Mapx) GetMapx(key string) *Mapx {
v, _ := m.Get(key).(map[string]interface{})
return (*Mapx)(&v)
}
func (m *Mapx) GetSlice(key string, fn func(item *Mapx, index int) bool) {
value := reflect.ValueOf(m.Get(key))
if value.Kind() != reflect.Slice {
return
}
for i := 0; i < value.Len(); i++ {
item := value.Index(i)
if item.Kind() != reflect.Invalid {
v, _ := item.Interface().(map[string]interface{})
if !fn((*Mapx)(&v), i) {
break
}
}
}
}
func (m *Mapx) Set(key string, val any) *Mapx {
(*m)[key] = val
return m
}
func (m *Mapx) Get(key string) any {
if m == nil {
return nil
}
var v any = map[string]interface{}(*m)
keys := strings.Split(key, dot)
for i := 0; i < len(keys); i++ {
if v == nil {
return nil
}
k := keys[i]
switch kind := reflect.TypeOf(v).Kind(); kind {
case reflect.Map:
_v := reflect.ValueOf(v).MapIndex(reflect.ValueOf(k))
if _v.Kind() != reflect.Invalid {
v = _v.Interface()
} else {
v = nil
}
case reflect.Slice:
if len(k) > 2 && k[0] == '[' && k[len(k)-1] == ']' {
idx, err := strconv.Atoi(k[1 : len(k)-1])
if err != nil {
return nil
}
_v := reflect.ValueOf(v).Index(idx)
if _v.Kind() != reflect.Invalid {
v = _v.Interface()
} else {
v = nil
}
}
case reflect.Struct:
_v := reflect.ValueOf(v).FieldByName(k)
if _v.Kind() != reflect.Invalid {
v = _v.Interface()
} else {
v = nil
}
case reflect.Ptr:
v = reflect.ValueOf(v).Elem().Interface()
i--
case reflect.Invalid:
return nil
default:
return nil
}
}
return v
}
func (m *Mapx) Remove(key string) {
delete(*m, key)
}
func (m *Mapx) Json() string {
b, _ := json.Marshal(&m)
return string(b)
}
func UnmarshalJSON(data []byte) (m *Mapx) {
_ = json.Unmarshal(data, &m)
return
}
// EncodeAliPaySignParams ("bar=baz&foo=quux") sorted by key.
func (m *Mapx) EncodeAliPaySignParams() string {
if m == nil {
return ""
}
var (
buf strings.Builder
keyList []string
)
for k := range *m {
keyList = append(keyList, k)
}
sort.Strings(keyList)
for _, k := range keyList {
if v := m.GetString(k); v != "" {
buf.WriteString(k)
buf.WriteByte('=')
buf.WriteString(v)
buf.WriteByte('&')
}
}
if buf.Len() <= 0 {
return ""
}
return buf.String()[:buf.Len()-1]
}
// EncodeURLParams ("bar=baz&foo=quux") sorted by key.
func (m *Mapx) EncodeURLParams() string {
if m == nil {
return ""
}
var (
buf strings.Builder
keys []string
)
for k := range *m {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
if v := m.GetString(k); v != "" {
buf.WriteString(url.QueryEscape(k))
buf.WriteByte('=')
buf.WriteString(url.QueryEscape(v))
buf.WriteByte('&')
}
}
if buf.Len() <= 0 {
return ""
}
return buf.String()[:buf.Len()-1]
}
func (m *Mapx) ValidateEmpty(keys ...string) error {
var emptyKeys []string
for _, k := range keys {
if m.IsNil(k) {
emptyKeys = append(emptyKeys, k)
}
}
if len(emptyKeys) > 0 {
return fmt.Errorf("[miss param error], %v", strings.Join(emptyKeys, ", "))
}
return nil
}