Spaces:
Running
Running
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 | |
} | |